Qt 5.8 released

I am happy to announce that Qt 5.8 has been released today and is available for download from qt.io. Qt 5.8 does of course come with Qt Creator 4.2.1 and an update to Qt for Device Creation. Qt 5.8 is a rather large release, containing quite a large set of new functionality. Let’s have a look at some of them:

Qt Lite

One of the main themes of Qt 5.8 has been to make Qt more flexible and easier to adopt to your use case, targeted especially at our embedded users. Qt Lite has been the codename of the project under which we did those changes.

Our goal has been to make it easier to configure Qt to exactly your needs and leave out features that you don’t need in your project. This brings major savings in the size of the compiled Qt libraries and thus your application.

Implementing support for this put us on a longer journey, where we rewrote most parts of the system that was being used to configure Qt. The new system cleans up a system that had grown over the last 15 years, and that also lead to many inconsistencies on how Qt was being configured on different host platforms.

As a result, we now have one unified system to configure the different parts of Qt. In addition to giving our users a lot more flexibility in configuring Qt, it will also ease our burden in supporting all the different ways Qt can be configured and used.

Using the new system allows you to create a Qt build tailored to exactly your use case. You can leave out all the features in Qt that you don’t need, saving ROM and RAM when deploying to your embedded device. To give you an idea of the size savings possible, the image below shows the size of the required Qt stack to run a small QML application:

Size of sample app using Qt 5.6 and a lite configuration of Qt 5.8

As you can see, the new configuration system allows for significant reductions in size and savings of more than 60% in binary size compared to Qt 5.6.

Qt Wayland Compositor

The Qt Wayland Compositor API that we included as a Technology Preview in Qt 5.7 is now fully supported in Qt 5.8. The module makes it very easy to create your own Wayland Compositor.

Qt Wayland Compositor make it very easy to implement your own custom home screen and application manager. This allows the creation of powerful and more complex embedded systems where you have multiple applications that have their own user interfaces. Qt Wayland Compositor supports handling multiple screens in an easy and transparent way. It comes with both QML and C++ APIs.

For more details, have a look at the API documentation and examples, as well as this blog post, which also features a tutorial.

Communication and Networking

Qt Serialbus has now graduated to be fully supported in Qt 5.8. It allows you to use Qt APIs for device bus communications and protocols. While the API is rather generic, this version includes implementations for CAN and Modbus.

Qt Network and Web Sockets gained full support for TLS PSK cyphersuites. Qt Network now supports configurable Diffie-Hellman parameters and HTTP/2 in QNetworkAccessManager.

Qt Bluetooth gains BTLE Peripheral support on macOS and iOS as well as BTLE Central support on WinRT.

Qt 5.8 also adds a new Qt Network Authorization module as a Technology Preview, currently supporting the OAuth 1 and 2 authentication schemes.

Qt QML and Quick

Quite a few things have happened in Qt QML and Qt Quick. The QML engine has gained support for caching binary representations of QML and JS files on disk, reducing startup time and memory consumption of the engine. The commercial only Qt Quick compiler is still supported in 5.8, but we are planning to merge it with the new caching infrastructure in the future, leading to a better performing and more tightly integrated solution.

The Qt Quick scene graph has undergone a larger refactoring, making it less dependent on OpenGL. This allowed us to add an experimental Direct3D 12 backend for Qt Quick, and does enable the creation of other backends e.g. based on the Vulkan graphics APIs.

In addition, the scene graph now supports partial updates to the screen if only a small area of the scenography changed. This brings some larger performance improvements to the Qt Quick 2D renderer.

We also used the changes to the scene graph as an opportunity to fold the functionality of the Qt Quick 2D renderer into Qt Quick directly. This implies that the Qt Quick 2D renderer does not exist as a standalone module in Qt 5.8 anymore.

Larger changes have also been done under the hood with respect to Mouse and Touch event handling, unifying them internally in a new QQuickPointerEvent class. This lays the foundation for future improvements to mouse and touch event handling, but doesn’t affect code using Qt Quick yet.

The Qt Quick Controls 2 have also gained a couple of new types such as dialogs, rounded buttons and tool separators. The Material and Universal styles have gained some new effects and support for a ‘system’ theme.

Qt Webengine

As always the Chromium version used by Qt Webengine has been updated, this time to Chromium 53. One long outstanding feature added in Qt 5.8 is the ability to print web pages. Many smaller new features have been added, amongst them a new QML API to define custom dialogs, tootips and context menus, and support for view-source: and some chrome: schemes.

Qt SCXML

Qt SCXML is now fully supported in Qt 5.8. The module makes is trivial to integrate SCXML based state machines into Qt. It builds directly onto the Qt Statemachine Framework, and extends it with with both a SCXML to C++ compiler and a runtime that allows loading SCXML based state machines.

Together with the Qt SCXML module, Qt Creator 4.2 gained support for editing state charts.

New Technology Previews

Also in Qt 5.8, we have new functionality that we chose to introduce as a Technology Preview.

Qt now compiles for both Apple’s tvOS and watchOS. While most of the functionality that we support on iOS should also work on tvOS, watchOS support is limited to the non-graphical functionality in Qt.

Qt Speech has been added as a new module adding support to text to speech functionality.

Other improvements

After the initial release of Qt 3D with Qt 5.7, the focus for 5.8 has been on maturing the module. A large amount of bug fixes and performance improvements have been made for the module.

Qt Charts has gained a Candlestick chart type and we have made the QOpenGLTextureBlitter API in Qt Gui public.

Our embedded platforms supported by Qt for Device Creation have gained better support for multi-screen systems when using the eglfs QPA plugin and support for 90/180 degree rotated screens.

Finally, many changes happened to our code base to make better use of the new features offered by C++11 and with that clean up and modernize our code base.

Thanks to the Qt Community

Qt 5.8 adds a lot of new functionality and improvements. Some of them would not have been possible without the help of the great community of companies and people that contribute to Qt by contributing new functionality, bug fixes, documentation, examples or bug reports. Thank you!

You can read more about the release and watch our launch video here, get Qt 5.8 from your Qt Account or www.qt.io/download. I hope you’ll like and enjoy the new release!

The post Qt 5.8 released appeared first on Qt Blog.

Qt SCXML and State Chart Support in Qt Creator

Qt has provided support for state machine based development since introduction of Qt State Machine Framework in Qt 4.6. With the new functionality introduced in Qt 5.8 and Qt Creator 4.2 state machine based development is now easier than ever before.

Qt 5.8 introduces fully supported Qt SCXML module that makes it easy to integrate SCXML based state machines into Qt. Previously SCXML has been imported to Qt from external tools, which is still possible. Now Qt Creator 4.2 introduces a new experimental visual state chart editor that allows creation and modification of state charts directly with Qt Creator IDE. Together with the new editor and other improvements in Qt Creator, state machine based development can be done completely within Qt Creator.

Here is a short screen cast that shows these new features in action. For demonstration purposes, the simple state machine driven example application with Qt Quick user interface Traffic Light is being recreated from scratch.

Note that the the editor is still experimental with Qt Creator 4.2 and the plugin is not loaded by default. Turn it on in Help > About Plugins (Qt Creator > About Plugins on macOS) to try it.

The post Qt SCXML and State Chart Support in Qt Creator appeared first on Qt Blog.

Creating devices with multiple UI processes using Wayland

In the early days of devices with a user interface, there was a single process that ran the user interface component. This was a nice way to separate out the user interface from the logic controlling the device and to ensure responsiveness for the end user. As hardware costs fell while simultaneously becoming more capable, we found more things for our devices to do. The user interface needed to be able to handle many more things, including asynchronous events and presenting information coming in from multiple places. Think of the transition from simple phones doing SMS, to feature phones and now smartphones which are more powerful than PCs of a decade ago. To run the whole UI of a smartphone in a single process would be considered madness today. Why not use similar techniques for building complex device user interfaces?

Devices with a multi-process user interface have several benefits:

  • Stability and robustness: By splitting your application into multiple functional units you maximize the stability of each application and if one application crashes it will not affect the other applications.
  • Efficient development: Separate teams can work on each application with lower risk of breaking something that the other team is working on.
  • Security: You can run applications with reduced privileges meaning that they can’t influence or access each other.
  • 3rd party application development: You can easily enable your device to be opened up to 3rd party app development. You can even mix and match applications from different UI toolkits.

 

Why Wayland?

multi-screen-demoHaving made the decision to have multiple process for the user interface display, the next technical problem to solve is getting the outputs of each process onto the display. Historically the approach has been to use X and write your own window manager.

The modern approach is to use Wayland, which is a simpler replacement for X.

  • It’s easy to develop and maintain
  • It’s a modern approach to window management designed with today’s graphical hardware in mind
  • The protocol is easily extendable
  • Wayland is the new industry standard for window management—it’s a common protocol that can be used by everyone, and is extended by everyone

With Wayland, the compositor is responsible for arranging and displaying each client’s content or output on the screen.

Wayland in Qt

Earlier versions of Qt provide the Qt Window System (QWS), which shares some of the design goals of Wayland. However, QWS only supports Qt-based clients and its architecture is not suited to modern OpenGL-based hardware. With Qt 5 we therefore started working on Wayland. Running Qt applications as Wayland clients has been officially supported since Qt 5.4.

Qt Wayland Compositor API

With Qt 5.8 we have released the Qt Wayland Compositor API, which allows you to create your own Wayland compositor. We give you all the tools you need to create a compositor in a simple way. You can easily define the UI and UX of your compositor with the power and simplicity of QML. If you still need or want to use C++, that’s also possible. There are also many other benefits of using the Qt Wayland Compositor API:

  • Creating multi-screen devices is simple
  • High abstraction level API means less lines of code to test and debug
  • Support for easily writing your own Wayland extensions—Allowing easy communication between clients and the compositor. E.g. you could write a protocol extension for telling clients to switch to night mode.
  • Built-in support for several shell extensions including XDG shell, WL Shell and IVI application allowing to connect to clients using any of these extensions

I hope this has piqued some interest in creating multi-process devices with the Qt Wayland Compositor API. To see for yourself how easily it can be done, check out the 10-minute tutorial below.

To get started, download Qt 5.8

The post Creating devices with multiple UI processes using Wayland appeared first on Qt Blog.

Qt Creator 4.2.1 released

We are happy to announce the release of Qt Creator 4.2.1. This is a pure bugfix release, and takes care of various important bugs.

Several properties of run configurations were only initialized when entering the Projects
mode, leading to various issues when running QMake projects, and projects that run custom executables, which have now been fixed.

In 4.2 we fixed iOS Simulator support for Xcode 8. Unfortunately there still were
problems, especially when running on iOS 10 simulator devices.
We adapted the way we start applications on the simulator, and this should now reliably
work again.

There have been a range of smaller bug fixes as well, please have a look at our change log
for more details.

Get Qt Creator 4.2.1

The opensource version is available on the Qt download page, and you find commercially licensed packages on the Qt Account Portal. Qt Creator 4.2.1 is also available through an update in the online installer. Please post issues in our bug tracker. You can also find us on IRC on #qt-creator on chat.freenode.net, and on the Qt Creator mailing list.

The post Qt Creator 4.2.1 released appeared first on Qt Blog.

Inside QImage (with a touch of Qt Quick and OpenGL)

QImage is the most common container for image data in Qt applications.

Getting a QImage that contains the pixel data of an image loaded from a file is fairly self-explanatory:

QImage img;
img.load("some_image.png");

This can then be used with QPainter, can be passed to widgets, and can also be utilized in Qt Quick scenes via custom image provider implementations. (although the latter would obviously be a massive overkill for image data coming from a file since that’s what the Image element provides out of the box anyway).

So far so good. Now, what if the image data is coming from somewhere else? For example a custom drawing made via QPainter, or an image that comes from some external engine, like a camera, scanner or computer vision framework?

The answer lies in some of the 9 constructors. The interesting ones for our purposes are the following:

QImage(int width, int height, Format format);
QImage(uchar *data, int width, int height, Format format, ...);
QImage(uchar *data, int width, int height, int bytesPerLine, Format format, …);
QImage(const uchar *data, int width, int height, ...);
QImage(const uchar *data, int width, int height, int bytesPerLine, Format format, …);

Let’s now take a look at some of the common use cases and how these constructors serve the specific needs of each case.

Case #1: Image data owned by the QImage

The common case when generating images on-the-fly, is using QPainter and its raster paint engine to draw into a QImage:

QImage img(640, 480, QImage::Format_ARGB32_Premultiplied);
img.fill(Qt::transparent);
QPainter p(&img);
p.fillRect(10, 10, 50, 50, Qt::red);
p.end();
...

Here the underlying image data is allocated and owned by img itself.

When it comes to the format for images that will be passed to Qt Quick, the basic recommendations (as of Qt 5.8) are the following:

  • In general, the first choice should be Format_ARGB32_Premultiplied. This is good because it is one of the preferred, fast formats for the raster paint engine, which QPainter uses under the hood when targeting a QImage, and the premultiplied format fits Qt Quick well since the scenegraph renderer and its materials rely on premultiplied alpha for blending. When creating textures for our image, the default, OpenGL-based Qt Quick scenegraph will avoid any potentially expensive QImage format conversion for ARGB32_Premultiplied images.
  • When there is no need for an alpha channel at all, due to our image being completely opaque, Format_RGB32 is a good alternative. This comes with the same benefit: no format conversion when creating an OpenGL scenegraph texture from such a QImage.

Other formats will lead to a convertToFormat() call at some point, which is not necessarily ideal. It is better to get the format right from the start.

It is worth noting that in order to get a proper no-conversion-by-Qt-on-CPU path, the OpenGL implementation must support GL_EXT_bgra, GL_EXT_texture_format_BGRA8888, or some of the vendor-specific variants. This can be relevant on older, OpenGL ES 2.0 only systems where BGRA support is not mandated by the GLES spec. In the absence of these (A)RGB32 image data will internally need either an additional swizzle step (this is what Quick and pretty much all old Qt 4 code does) or a conversion to a byte ordered QImage format (preferred by some of the newer code in QtGui and elsewhere), because the (A)RGB32 formats are not byte ordered.

What are byte ordered however are the Format_RGB(A|X)8888[_Premultiplied] formats introduced in Qt 5.2. These are nice because when read as bytes, the order is R, G, B, A on both little and big endian systems, meaning the image data can be passed to a glTex(Sub)Image2D call using a GL_RGBA format with a GL_UNSIGNED_BYTE data type as-is.

  • When targeting older OpenGL ES 2.0 systems is a must, custom OpenGL rendering code (for example, inside a QOpenGLWindow, QOpenGLWidget, QQuickFramebufferObject, etc.) can benefit from using QImages with a byte ordered format like Format_RGBA8888, simply because there is less code to write. (no manual swizzling or extra QImage format conversion is needed when BGRA support is missing)
  • Some of QtGui’s OpenGL helpers that may be used by such code, most notably QOpenGLTexture, also prefer Format_RGBA8888 when working with QImage, and will kick off a conversion for other formats.

Therefore, the older default recommendation of using Format_ARGB32_Premultiplied or Format_RGB32 is not necessarily valid always. In the context of Qt Quick however, sticking with these formats will typically still be the right choice.

Case #2: Wrapping external, read-only image data

Now, what if the image data is readily available from an external engine? The common solution here is to use the QImage constructor taking a const uchar pointer.

void *data = ...
QImage wrapper(static_cast<const uchar *>(data), 640, 480, QImage::Format_RGB32);
// 'wrapper' does not own the data.
// 'data' must stay valid until 'wrapper' is alive.

There are no memory allocations and copies made here. It is up to the application to ensure the width, height, format, and optionally the bytes per line reflect the raw image data received from the other framework or engine.

Like many other container classes in Qt, QImage is using implicit sharing. This is handy because this way a QImage can be passed or returned by value without having to worry avoid expensive copies of the actual image data.

Instances created from a const uchar * are special in the sense that any attempt to modify the QImage (via a non-const function) detaches (makes a copy) regardless of the reference count. Hence attempts to modify to original, external data are futile:

const uchar *data = ...
QImage wrapper(data, ...);
wrapper.setPixelColor(5, 5, Qt::green);
// 'wrapper' is not a wrapper anymore,
// it made a full copy and got detached

Note that while this is all nice in theory, and the zero-copy approach is great in some cases, in practice making copies of the data is often unavoidable due to the need for format conversions in order to match the needs of the various frameworks. For example when interfacing with OpenCV, the code (taken from here) to convert a CV_8UC4 image into a QImage could look like this:

QImage mat8ToImage(const cv::Mat &mat)
{
    switch (mat.type()) {
    ...
    case CV_8UC4: {
        QImage wrapper(static_cast<const uchar *>(mat.data), mat.cols, mat.rows, int(mat.step), QImage::Format_RGB32);
        return wrapper.rgbSwapped();
    }
    ...

(NB! It does not matter if we use the const or non-const pointer variant of the constructor here. A copy will be made either way due to the semantics of rgbSwapped())

Case #3: Wrapping and modifying external image data

What about the constructor taking an uchar pointer? As the non-const argument suggests, this allows modifying the external, non-owned data via a wrapping QImage, without making copies of the image data. Modification often means opening a QPainter on the QImage:

void *data = ...
QImage img(static_cast<uchar *>(data), 640, 480, QImage::Format_RGB32);
QPainter p(&img);
p.fillRect(10, 10, 50, 50, Qt::red);
p.end();
... // 'data' must stay valid as long as 'img' is alive

Here we paint a red rectangle on top of the existing content.

This is made possible by a perhaps at first confusing feature of QImage: with non-owned, non-read-only data modification attempts will not detach when the reference count is 1 (i.e. the image data is not shared between multiple QImage instances).

Compare this behavior with something like QString::fromRawData() which explicitly says: Any attempts to modify the QString or copies of it will cause it to create a deep copy of the data, ensuring that the raw data isn’t modified.

There a container associated with external data always makes a copy, and does not support modifying the external data. With QImage this is not acceptable, since the ability to change the pixels of an image from an arbitrary source without making a copy is a must have.

See this little example project for a demonstration of painting into a manually allocated image. It also demonstrates one potential issue one may run into when getting started with such a QImage:

void drawStuff_Wrong(QImage image)
{
    QPainter p(&image); // oops
    p.fillRect(10, 10, 50, 50, Qt::red);
}

QImage wrapper(data, 640, 480, QImage::Format_RGB32);
drawStuff_Wrong(wrapper);

This is clearly broken. The red rectangle will not appear in the original image pointed to by ‘data’. Due to passing to the function by value the image gets its refcount increased to 2, and so the modification attempt when opening the QPainter has to detach with a full copy. The solution here is to pass by pointer or reference. (or yet better do not pass at all; QImage instances referencing external data should ideally be isolated as much as possible, in order to avoid issues like the one above)

Accessing the image data

And last but not least, let’s talk about accessing the bytes of a QImage.

For read access, something like QImage::pixel() clearly does not scale when having to examining a larger part of the image. Instead, use constBits() or constScanLine().

QImage img(640, 480, QImage::Format_ARGB32_Premultiplied);
const uchar *p = img.constBits();
...
// 'p' is valid as long as 'img' is alive

Read-write access is done via bits() and scanLine(). These exist in both const and non-const version. The const version are in effect same as constBits() and constScanLine(). In practice it is strongly recommended to use constBits() and constScanLine() whenever read-only access is desired, in order to avoid accidentally invoking the non-const bits() or scanLine(), and making expensive and totally unnecessary copies of the image data.

QImage img1(640, 480, QImage::Format_RGB32);
QImage img2 = img1;
const uchar *p = img1.bits();
// ouch! that's the non-const bits(). img1 detaches.
// we only wanted read access and yet wasted time with a copy.

Due to img1 not being const this should have been:

QImage img1(640, 480, QImage::Format_RGB32);
QImage img2 = img1;
const uchar *p = img1.constBits();
// no copy, img1 and img2 still share the same data

The non-const versions detach when multiple instances share the same data or when the image wraps read-only, external data (via the const uchar * constructor).

That is all for now. Hope this clears up some of the uncertainties that may arise when looking at the QImage API for the first time, and helps to avoid some of the pitfalls when working with external image data. Happy hacking with QImage!

The post Inside QImage (with a touch of Qt Quick and OpenGL) appeared first on Qt Blog.

Qt Speech (Text to Speech) is here

I’m happy that with Qt 5.8.0 we’ll have Qt Speech added as a new tech preview module. It took a while to get it in shape since the poor thing sometimes did not get the attention it deserved. We had trouble with some Android builds before that backend received proper care. Luckily there’s always the great Qt community to help out.
Example application show Qt Text to Speech
What’s in the package? Text to speech, that’s about it. The module is rather small, it abstracts away different platform backends to let you (or rather your apps) say smart things. In the screen shot you see that speech dispatcher on Linux does not care much about gender, that’s platform dependent and we do our best to give you access to the different voices and information about them.

Making the common things as simple as possible with a clear API is the prime goal. How simple?
You can optionally select an engine (some platforms have several). Set a locale and voice, but by default, just create an instance of QTextToSpeech and connect a signal or two. Then call say().

m_speech = new QTextToSpeech(this);
connect(m_speech, &QTextToSpeech::stateChanged,
        this, &Window::stateChanged);
m_speech->say("Hello World!");

And that’s about it. Give it a spin. It’s a tech preview, so if there’s feedback that the API is incomplete or we got it all wrong, let us know so we can fix it ASAP. Here’s the documentation.

I’d like to thank everyone who contributed, Maurice and Richard at The Qt Company, but especially our community contributors who were there from day one. Jeremy Whiting for general improvements and encouragement along the way (I bet he almost gave up on this project). Samuel Nevala and Michael Dippold did implement most of the Android backend, finally getting things into shape. Thanks!

You may wonder about future development of Qt Speech. There are some small issues in the Text to Speech part (saving voices and the current state in general should be easier, for example). When it comes to speech recognition, I realized that that’s a big project, which deserves proper focus. There are many exciting things that can and should be done, currently I feel we need proper research of all the different options. From a simple command/picker mode to dictation, from offline options and native backends to the various cloud APIs. I’d rather end up with a good API that can wrap all of these in a way that makes sense (so probably a bunch of classes, but I don’t have a clear picture in my mind yet) than rushing it. I hope we’ll get there eventually, because it’s certainly an area that is important and becoming more and more relevant, but I assume it will take some time until we have completed the offering.

The post Qt Speech (Text to Speech) is here appeared first on Qt Blog.

How to shoot yourself in the foot using only a scene graph (neat optimization trick inside)

by Eskil Abrahamsen Blomfeldt (Qt Blog)

I am trying to get into the habit of blogging more often, also about topics that may not warrant a white paper worth of text, but that may be interesting to some of you. For those of you who don’t know me, I am the maintainer of the text and font code in Qt, and recently I came across a curious customer case where the optimization mechanisms in the Qt Quick scene graph ended up doing more harm than good. I thought I would share the case with you, along with the work-around I ended up giving to the customer.

Consider an application of considerable complexity: Lots of dials and lists and buttons and functionality crammed into a single screen. On this screen there are obviously also labels. Thousands of static labels, just to describe what all the complex dials and buttons do. All the labels share the same font and style.

Narrowing the example down to just the labels, here is an illustration:

import QtQuick 2.5
import QtQuick.Window 2.2

Window {
    id: window
    visible: true
    title: qsTr("Hello World")
    visibility: Window.Maximized

    Flow {
        anchors.fill: parent
        Repeater {
            model: 1000
            Text {
                text: "Hello World"
            }
        }
    }
}

Now, the way the scene graph was designed, it will make an effort to bundle together as much of a single primitive as possible, in order to minimize the number of draw calls and state changes needed to render a scene (batching). Next, it will try to keep as much as possible of the data in graphics memory between frames to avoid unnecessary uploads (retention). So if you have a set of text labels that never change and are always visible, using the same font, essentially Qt will merge them into a single list of vertices, upload this to the GPU in one go and retain the data in graphics memory for the duration of the application.

Example screenshot

Artist’s impression of a complex Qt application

We can see this in action by setting the environment variable QSG_RENDERER_DEBUG=render before running the application above. In the first frame, all the data will be uploaded, but if we cause the scene graph to re-render (for instance by changing the window size), we see output like this:

Renderer::render() QSGAbstractRenderer(0x2a392d67640) "rebuild: none"
Rendering:
 -> Opaque: 0 nodes in 0 batches...
 -> Alpha: 1000 nodes in 1 batches...
 - 0x2a39351fcb0 [retained] [noclip] [ alpha] [  merged]  Nodes: 1000  Vertices: 40000  Indices: 60000  root: 0x0 opacity: 1
 -> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, upload(opaque/alpha): 0/0, render: 0

From this we can read the following: The application has one batch of alpha-blended material, containing 1000 nodes. The full 40000 vertices are retained in graphics memory between the frames, so we can repaint everything without uploading the data again.

So far so good.

But then this happens: Someone adds another label to our UI, somewhere in the depths of this complex graph of buttons, dials and labels. This label is not static, however, but shows a millisecond counter which is updated for every single frame.

While the scene graph does the correct and performant thing for most common use cases, the introduction of this single counter item in our scene breaks the preconditions. Since the counter label will be batched together with the static text, we will invalidate all the geometry in the graph every time it is changed.

To see what I mean, lets change our example and run it again.

import QtQuick 2.5
import QtQuick.Window 2.2

Window {
    id: window
    visible: true
    title: qsTr("Hello World")
    visibility: Window.Maximized
    property int number: 0

    Flow {
        anchors.fill: parent
        Repeater {
            model: 1000
            Text {
                text: index === 500 ? number : "Hello World"
            }
        }
    }

    NumberAnimation on number {
        duration: 200
        from: 0
        to: 9
        loops: Animation.Infinite
    }
}

The example looks the same, except that the 501st Text item is now a counter, looping from 0 to 9 continuously. For every render pass, we now get output like this:

Renderer::render() QSGAbstractRenderer(0x1e671914460) "rebuild: full"
Rendering:
 -> Opaque: 0 nodes in 0 batches...
 -> Alpha: 1000 nodes in 1 batches...
 - 0x1e672111f60 [  upload] [noclip] [ alpha] [  merged]  Nodes: 1000  Vertices: 39964  Indices: 59946  root: 0x0 opacity: 1
 -> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, upload(opaque/alpha): 0/1, render: 0

As we can see, we still have a single batch with 1000 nodes, but the data is not retained, causing us to upload almost 40000 vertices per frame. In a more complex application, this may also invalidate other parts of the graph. We could even end up redoing everything for every frame if we are especially unlucky.

So, presented with this case and after analyzing what was actually going on, my first goal was to find a work-around for the customer. I needed to come up with a way to separate out the counter label into its own batch, without changing how anything looked on screen. There may be more ways of doing this, but what I ended up suggesting to the customer was to set clip to true for all the counter labels. Giving the counters a clip node parent in the graph will force them out of the main batch, and the updates will thus be isolated to the clipped part of the scene graph.

import QtQuick 2.5
import QtQuick.Window 2.2

Window {
    id: window
    visible: true
    title: qsTr("Hello World")
    visibility: Window.Maximized
    property int number: 0

    Flow {
        anchors.fill: parent
        Repeater {
            model: 1000
            Text {
                text: index === 500 ? number : "Hello World"
                clip: index === 500
            }
        }
    }

    NumberAnimation on number {
        duration: 200
        from: 0
        to: 9
        loops: Animation.Infinite
    }
}

Still the same code, except that the clip property of the 501st Text item is now set to true. If we run this updated form of the application with the same debug output, we get the following:

Renderer::render() QSGAbstractRenderer(0x143890afa10) "rebuild: partial"
Rendering:
 -> Opaque: 0 nodes in 0 batches...
 -> Alpha: 1000 nodes in 3 batches...
 - 0x143898ee6d0 [retained] [noclip] [ alpha] [  merged]  Nodes:  500  Vertices: 20000  Indices: 30000  root: 0x0 opacity: 1
 - 0x143898ec7e0 [  upload] [  clip] [ alpha] [  merged]  Nodes:    1  Vertices:     4  Indices:     6  root: 0x14389a3a840 opacity: 1
 - 0x143898edb90 [retained] [noclip] [ alpha] [  merged]  Nodes:  499  Vertices: 19960  Indices: 29940  root: 0x0 opacity: 1
 -> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, upload(opaque/alpha): 0/0, render: 0

As you can see from the output, the text is now divided into three batches instead of one. The first and last are retained between frames, causing the full upload for each frame to be an insignificant 4 vertices. Since the clip rect contains the bounding rect of the text, we will not actually clip away any pixels, so the application will still look the same as before.

So all is well that ends well: The customer was happy with the solution and their performance problems were fixed.

Also, I gained some ideas on how we can improve the Qt Quick API to make it easier for users to avoid these problems in the future. Since we want performance to be stable from the first frame, I don’t think there is any way to get around the need for users to manually identify which parts of the graph should be isolated from the rest, but I would like to have a more obvious way of doing so than clipping. My current idea is to introduce a set of optimization flags to the Qt Quick Text element, one of which is Text.StaticText, sister to the QStaticText class we have for QPainter-based applications.

In the first iteration of this, the only effect of the flag will be to ensure that no label marked as StaticText will ever be batched together with non-static text. But down the road, maybe there are other optimizations we can do when we know a text label never (or rarely) changes. And this is just one of a few optimization APIs I want to add to Qt Quick Text in the near future, so stay tuned! 🙂

The post How to shoot yourself in the foot using only a scene graph (neat optimization trick inside) appeared first on Qt Blog.

Qt Was Really Everywhere at CES2017

CES 2017 was full of autonomous driving, artificial intelligence and virtual assistants. It was great to see the momentum in the industry towards the future. While all of the innovative, future oriented technologies were present, there was also room for more modern technologies such as plastic mobile phone covers. Somewhere in between today and tomorrow were digital cockpits with a variety of implementations.

Qt based technologies were demoed everywhere by OEMs, Tiers1, silicon vendors and various solution providers. Some partners had made it very easy to find Qt – both Harman and Greenhills for example had hard printed Qt logos on their booth infrastructure, HERE and Pelagicore had Qt logos on the software, while some partners (when asked) said that Qt was the technology driving their demos. Of course, there were also product demos that were on display where one just needed to have some inside information to know that the demo was using Qt.

Qt was presented in many different roles: UI used to demonstrate underlying hardware technology, developer platform for generic applications or a holistic digital cockpit solution for traditional cars, as well as driver’s/passengers’ UI for autonomous cars. Most interestingly there was not a single competitor’s technology covering all of these use cases. Based on my biased, one-man market study I could claim Qt was the most versatile automotive technology at CES.

Using Qt in hardware demoes is easy to understand. Qt enables fast UI creation if the partner wants to demo for example performance of the underlying platform. In addition, Qt was used to visualize the sensor data either as for pure demo or real use case in autonomous driving scenario.

As Qt is used in over 70 different industries the applications are easy to find. Most interestingly big service / software brands have started to use Qt in OEM specific application development. Good example being Skype for Business by Volvo.

The trend from IVIs and instrument clusters to digital cockpits was very clear across the Tier1s and OEMs. The more futuristic the cockpit you saw the more difficult it was to split the functionality. Based on several discussions with OEMs, Tier1s and other solution providers the future is all about one software platform on one hardware system. It was not only The Qt Company who had selected Qt for comprehensive digital cockpit solution, the whole industry is looking at Qt.

In short, Qt is everywhere at CES2017 was true.

 

The post Qt Was Really Everywhere at CES2017 appeared first on Qt Blog.

“Unboxing” the Android Things Developer Preview

Android Things is Google’s answer to creating an environment for IoT devices. Take a slimmed down Android build, add some sensor-specific APIs, and provide it on a number of powerful pre-integrated micro-boards and you have a ready-made platform for building a host of upcoming IoT devices. Android Things can take advantage of many existing Android libraries, toolkits, and APIs, making it easier and quicker for developers to turn ideas into product. What’s not to like?

We decided to test this theory by checking out the Android Things Developer Preview on a Raspberry Pi 3. We were looking to assess the overall experience, to understand what types of products it is targeting and to try to determine how well it can support Qt.

Raspberry Pi 3 (Model B)

One of my very first observations is that Google does not provide the source, just a pre-built image. This makes it difficult to customize the image and puts us at the mercy of Google for updates to any of the contained components or packages like the kernel or SSL library. Let’s hope that this will change once we’re beyond the Developer Preview stage.

Once you have the image loaded onto a board, it’s time to boot it and take it for a spin. This is an appropriate time to get a coffee — and you’ve got the time to drive to Starbucks — because booting Android Things takes a very long time. Linux builds for Yocto or Debian on the same hardware boot significantly faster than Android Things, so we can probably assume the boot process hasn’t yet been fine-tuned. Without knowing the final boot speed of an Android Things product, you may want to plan use cases around a system that’s always on and rarely needs a reboot, or that isn’t real-time and can afford a boot process that takes minutes.

The Android Things Preview on the Raspberry Pi 3 doesn’t provide OpenGL ES support or a virtual keyboard, which severely limits what type of Android Java apps will run. (Unfortunately, that also means it cannot support Qt QML either.) It’s pretty safe to say that if your device plans to have a full smartphone-like display, you might not want to use Android Things anyway. Although it does support frame buffer graphics, without hardware acceleration the graphics are quite pokey. Our guess is that even if Android Things will eventually support OpenGL ES, its best application will be for a headless configuration or one where your display needs aren’t too sophisticated.

Unfortunately, boot speed and graphics aren’t the only things that are sluggish. Running and installing apps are quite slow: first time loads for a Java app are around 20 seconds, and for a Qt app around 25 seconds. This delay is likely due to the AOT compiler, because things speed up dramatically to a boot in just 2-3 seconds on subsequent loads. While this is a pain for developers who will suffer these load times for each new build, the AOT compiling means that customers would only notice a slow experience first time out-of-the-box.

Now for the good news. Qt developers will be happy to know that Qt Creator works very well with Android Things — running and debugging apps just works. And not only will QWidget-based applications run on Android Things, they’re even faster than the platform’s native Android Java widgets. This may not be saying much without GPU-accelerated graphics but any speed improvement is a bonus.

Also good news is the device’s security. Android Things uses the Android security/permissions model across the board, letting you have complete security control of your IoT device access, and placing all apps in isolated containers by default. With IoT security being a primary concern, built-in security from the ground up is most welcome.

Finally, Android Things is Apache 2 licensed. People who are building an IoT device to be sold as a product will appreciate that they don’t have to open up their source code to the world. It is a disadvantage to those who are tinkering but this choice (and the Google source ownership) pretty clearly point to a commercial product bias.

Conclusion

Android Things

If you’re an Android fan, you’ll like where Android Things is going. It’s a bit on the slow side, as it’s clearly designed with certain use cases in mind — like little (or no) display and infrequent reboots — but the benefits of Android development may outweigh the disadvantage of carrying around a massive Android runtime. It will definitely suffer on low-end devices but we can hope that optimizations will be made as more programmers get their hands on it. We’ll certainly be keeping our eyes on it and, as running C++ can do nothing but help the overall speed, we’ll be trying to make sure that it supports Qt as best as possible.

The post “Unboxing” the Android Things Developer Preview appeared first on KDAB.

Which OpenGL implementation is my Qt Quick app using today?

Qt Quick-based user interfaces have traditionally been requiring OpenGL, quite unsurprisingly, since the foundation of it all, the Qt Quick 2 scenegraph, is designed exclusively with OpenGL ES 2.0 (the top of the line for mobile/embedded at the time) in mind. As you may have heard, the graphics API story is a bit more inclusive in recent Qt versions, however the default OpenGL-based rendering path is, and is going to be, the number one choice for many applications and devices in the future. This raises the interesting question of OpenGL implementations.

Wait, there is more than one? Isn’t there one for my graphics card, and that’s it?

Kind of, but not quite.

The vendor-provided OpenGL implementation is one thing, but is is not always there to begin with (anyone who attempted to deploy Quick apps on a wide range of older machines running e.g. Windows 7 with no graphics driver installed could likely talk a lot about this…), while in some cases there are alternative options, for instance an open-source stack like Mesa. Some of these stacks can then provide multiple ways of operation (think software rasterizers like Mesa llvmpipe or Direct3D WARP).

As an example, let’s take a look at Windows. The Windows-specific area of the Qt documentation describes the options pretty well. To summarize, one may be using OpenGL proper (a vendor-provided ICD behind opengl32.dll), ANGLE in D3D9 mode, ANGLE in D3D11 mode, ANGLE with the D3D11 WARP software rasterizer, an OpenGL software rasterizer provided by Mesa llvmpipe. That is no fewer than 5 options, and the choice can be made based on the built-in GPU card/driver blacklist or environment variables or hard-coded application preferences. All this is not exactly rocket science, but it does require a certain level of awareness from the developer during development, possibly when reporting bugs and support requests, and naturally also when planning deployment.

Why does this matter?

  • It is not always obvious what is going on. Just starting a Qt Quick application and getting some output does not mean rendering is happening on the optimal path. When the application does not render at the expected speed, the very first thing to verify is if the graphics stack is the expected one. There can always be an unexpected environment variable or blacklist rule present, or the application may pick the wrong graphics stack when there are multiple ones present in the system.
  • Some of the options come with a set of drawbacks and affect the runtime behavior (most importantly, the choice of the Qt Quick render loop used behind the scenes), which in turn can affect performance and can even disable features. (No threaded render loop? No render thread Animators for you.)
  • When reporting issues to the Qt Project bug tracker or Qt Support, it is essential to provide the necessary information about the runtime environment. A mere “OpenGL on Windows” or “Qt Quick on an ARM device” is never sufficient.

QSG_INFO=1 is your friend

When in doubt about graphics performance or before attempting to troubleshoot any sort of graphics issues, do set the QSG_INFO environment variable to 1 and rerun your Qt Quick application.

An alternative in modern Qt versions is to enable the qt.scenegraph.general logging category.

This will print something like the following either on the console or the debug output: (on Windows you can use DebugView for non-console apps when not launching from Qt Creator)

qt.scenegraph.general: threaded render loop
qt.scenegraph.general: Using sg animation driver
qt.scenegraph.general: Animation Driver: using vsync: 16.95 ms
qt.scenegraph.general: texture atlas dimensions: 2048x2048
qt.scenegraph.general: R/G/B/A Buffers:    8 8 8 0
qt.scenegraph.general: Depth Buffer:       24
qt.scenegraph.general: Stencil Buffer:     8
qt.scenegraph.general: Samples:            0
qt.scenegraph.general: GL_VENDOR:          NVIDIA Corporation
qt.scenegraph.general: GL_RENDERER:        GP10B (nvgpu)/integrated
qt.scenegraph.general: GL_VERSION:         OpenGL ES 3.2 NVIDIA 367.00
qt.scenegraph.general: GL_EXTENSIONS:      ...
qt.scenegraph.general: Max Texture Size:  32768
qt.scenegraph.general: Debug context:     false

What does this tell us?

The OpenGL vendor, renderer and version strings. In the example above we see Qt Quick is using an OpenGL ES 3.2 context on some NVIDIA embedded platform, using the vendor’s driver. This look good.

Now, if there happen to be references to llvmpipe, like in the below example, then that should immediately raise a flag: your application is rendering via a software rasterizer. If this is expected, fine. If not, then you should figure out why, because performance is seriously affected (you are not using the GPU at all).

GL_VENDOR: VMware, Inc.
GL_RENDERER: Gallium 0.4 on llvmpipe (LLVM 3.6, 128 bits)
GL_VERSION: 3.0 Mesa 11.2.2

Let’s take another example, this time with ANGLE. Here I just forced the usage of ANGLE by setting QT_OPENGL=angle on an otherwise fully OpenGL capable system:

qt.scenegraph.general: windows render loop
qt.scenegraph.general: Using sg animation driver
t.scenegraph.general: Animation Driver: using vsync: 16.67 ms
qt.scenegraph.general: texture atlas dimensions: 512x512
qt.scenegraph.general: R/G/B/A Buffers:    8 8 8 8
qt.scenegraph.general: Depth Buffer:       24
qt.scenegraph.general: Stencil Buffer:     8
qt.scenegraph.general: Samples:            0
qt.scenegraph.general: GL_VENDOR:          Google Inc.
qt.scenegraph.general: GL_RENDERER:        ANGLE (NVIDIA GeForce GTX 960 Direct3D11 vs_5_0 ps_5_0)
qt.scenegraph.general: GL_VERSION:         OpenGL ES 2.0 (ANGLE 2.1.0.8613f4946861)
qt.scenegraph.general: GL_EXTENSIONS:      ...
qt.scenegraph.general: Max Texture Size:  16384
qt.scenegraph.general: Debug context:     false

The key points are that (1) we are using ANGLE, (2) it is using its D3D11 backend, and (3) the Qt Quick scenegraph is using the (somewhat ill-named) ‘windows’ render loop, meaning no dedicated render thread is present. The usage of D3D9 or D3D11 WARP can be recognized from the renderer string in the same way.

Then there is the Qt Quick scenegraph’s active render loop. This can be threaded, basic or windows. In recent Qt versions the scenegraph documentation describes all of these quite well, including the logic for choosing the loop to use. For experimenting or troubleshooting one can always override by setting the environment variable QSG_RENDER_LOOP to one of the three render loop names.

One common problem, mainly on embedded systems, is sometimes the bizarre speed up of animations. If you find that QML animations are running a lot faster than they should be and that the threaded render loop is in use, there is a good chance the issue is caused by the missing or incorrect vertical sync throttling. Solving this will be platform specific (e.g. in some cases one will need to force making a dedicated FBIO_WAITFORVSYNC ioctl, see QT_QPA_EGLFS_FORCEVSYNC), but armed with the logs from the application at least the root cause can be uncovered quickly and painlessly. (NB as a temporary workaround one can force the basic render loop via QSG_RENDER_LOOP=basic; this will provide more or less correct timing regardless of vsync at the expense of losing smooth animation)

Your other friends: qtdiag and contextinfo

Note that the scenegraph’s log only provides limited system information. It is great for strictly graphics and Quick-related issues, but when making bug reports, especially for Windows, it is strongly recommended to post the output of the qtdiag utility as well. This will provide a lot wider set of system information.

Additionally, the contextinfo example in examples/opengl/contextinfo is a good tool to troubleshoot basic OpenGL bringup problems. Launch it normally, click Create Context, see what happens: does the triangle show up? Does it rotate smoothly? Are the vendor and renderer strings as expected? Then set QT_OPENGL=angle and re-run. Then set QT_ANGLE_PLATFORM=d3d9 and re-run. Then set QT_OPENGL=software and, assuming the opengl32sw.dll shipped with the pre-built Qt packages is accessible, re-run. Or on Linux with Mesa, set LIBGL_ALWAYS_SOFTWARE=1 and see what happens. And so on.

Why am I not getting the right GL implementation?

Now, let’s say the logs reveal we are stuck with a software rasterizer and our beautiful Qt Quick UI runs sluggishly in a maximized full HD window. What can we do to figure out why?

On Windows, enable the logging category qt.qpa.gl. (e.g. set QT_LOGGING_RULES=qt.qpa.gl=true) This will tell why exactly the OpenGL implementation in question was chosen. The typical reasons are:

  • opengl32.dll not providing OpenGL 2.0
  • the card PCI ID or driver vendor/version matching a built-in GPU blacklist rule
  • having the QT_OPENGL or QT_ANGLE_PLATFORM environment variables set
  • having a hard-coded request like Qt::AA_UseSoftwareOpenGL via QCoreApplication::setAttribute().

On Linux, there are typically three reasons:

  • With Mesa, the environment variable LIBGL_ALWAYS_SOFTWARE forces a software rasterizer. Check if it is set, and if it is, investigate why.
  • In some environments no hardware acceleration is available. In some virtual machines for example, you will be stuck with a Mesa llvmpipe based rendering path.
  • Multiple graphics stacks. This can happen on any kind of Linux systems, but is more likely to happen on some embedded device oriented distros. Running ldd on the application and the relevant Qt libraries, and looking for libGLESv2.so may help to figure out what is going on.

A cautionary tale

The Raspberry Pi has at least three OpenGL solutions as of today: the Broadcom graphics stack, Mesa with llvmpipe (software rasterizer), and the upcoming Mesa with proper GPU acceleration (VC4) path.

Unfortunately this can lead to an unholy mess due to some distros prefering to ship Mesa llvmpipe in order to provide some sort of OpenGL under X11 (which the Broadcom stack does not support): Qt applications may unexpectedly pick up Mesa when they should use Broadcom (for Dispmanx without X11), while they may end up with disastrous performance under X11 due to overdriving the poor CPU with software GL rasterization.

While it is easy to blame Qt, JavaScript VMs, scripting languages, C++, and everything but the kitchen sink when one’s Quick application runs slowly, the solution to figure out the root cause is often even easier: QSG_INFO=1.

That’s all for now. Take care, and make sure to check the output from QSG_INFO=1 next time.

The post Which OpenGL implementation is my Qt Quick app using today? appeared first on Qt Blog.

QFace – A generator framework

QFace is a generator framework based on a common modern IDL. It is not a generator as such but enforces a common IDL format and provides a library to write your own generator. It is actually very easy to create your own generator and generate your custom solution based on your needs from the same IDL.

// echo.qface
module org.example 1.0;

/**!
The echo interface to call someone
on the other side
*/
interface Echo {
    readonly Message lastMessage;
    void echo(Message message);
    event void callMe();
};

struct Message {
    string text;
};

The IDL is designed after the Qt/QML interface and as such is optimized to generate source code used with Qt C++ or Qt QML, but it is not limited to this use case.

QFace Landing Page

QFace is already very fast by design and suitable for large IDL document sets. Additionally it can use a cache to avoid parsing unchanged IDL documents. It can also automatically avoid writing new files if the target file has the same content.

QFace is written out of the learnings of using IDLs in other large projects. Often in the project you need to adjust the code generation but in many generators this is awfully complicated. Or you need to run a report on the documents or generate specific documentation. In QFace this is enabled by having a very flexible code generation framework which enforces the same IDL.

Now you write a small script using qface to generate your code

# mygenerator.py
from qface.generator import FileSystem, Generator

# load the interface files
system = FileSystem.parse('echo.qface')
# prepare the generator
generator = Generator(searchpath='.')

# iterate over the domain model
for module in system:
    for interface in module:
        # prepare a context object
        ctx = { 'interface': interface }
        # use header.h template with ctx to write to a file
        generator.write('{{interface|lower}}.h', 'header.h', ctx)

Depending on the used generator it reads the input file and runs it through the generator. The output files are written relative to the given output directory. The input can be either a file or a folder.

QFace Landing Page


Mobile Card Games: How to Make the Most of User Retention & Loyalty

According to statistics released by the Flurry team, developers of mobile card games may be sitting on gold mines.

Card games can be extremely lucrative. They have the highest retention rates of any game genre right now. And they’re also played at a higher frequency than any other mobile game genre.

So how do you get in on this action? With our open-source card game example of course! We’ve released our own card game and seen the results for ourselves. The cool thing is; we’ve made the full source code of this card game example available in V-Play!

You can use this open-source card game as the basis for your own game once you download V-Play. It’s completely free to use and you can change it in any way you like. You can even charge people money to play it!

Don’t like card games? Then you’ll be happy to hear that weather apps can be just as good. And we’ve got an open-source weather app example for that too. Read on to find out how you can enjoy the high retention and use-frequency rates of these two app and game genres.

The User Loyalty Matrix

Below is the user loyalty matrix for the top mobile app and game genres on iOS devices.

iOS App Loyalty with circle

User Loyalty Matrix via Flurry

This matrix give us three vital pieces of information about each app or game genre. Besides “Frequency of Use-Per-Week” and “Retention Over 30 Days”, the matrix is also split into 4 quadrants. Each quadrant represents what type of use each app or game genre receives.

Below, you can see a further breakdown of user loyalty according to game sub-category.
Sub-Category Loyalty with rectangle

Gaming Sub-Category User Loyalty Chart via Flurry

As you can see for yourself, card games outperform every competitor when it comes to both retention and use-frequency. In fact, the use-frequency of card games is almost double that of arcade games. And when it comes to retention, card games blow away every genre besides Casino & Dice.
With such dedicated players, it’s easy to see why card games are the most lucrative game genre. Fortunately, V-Play includes a ready-made card game template for you to get in on the action right now!
Before that, let’s take a quick look at the 4 quadrants of app and game use. This will let you see how your current or expected app and game projects should work out.

The Different Forms of App & Game Usage

Daily Interaction from a Loyal User Base

Quadrant I includes apps & games that have high retention rates and almost daily use. Weather apps fall into this quadrant. This is because users like to check weather apps daily for upcoming forecasts. Unless a forecast is terribly wrong, they’re unlikely to change their weather app. You can see more about our weather app template here.

Card games fall into this category as well. This is because card games are social games that people play with their friends. People want to play a game they know with people they know. This means they often return to the same card game for long periods of time.

High Interaction after Installation but Poor User Loyalty

Quadrant II includes apps & games that people use a lot after a first installation, but then see a decrease in loyalty over time. Apps & games in this quadrant lack an everyday use or the social features.

In this category you will find productivity apps, word games, sports games and puzzles.

StockSnap_YEBI1N2K7S

Installed, Used and Discarded – No User Loyalty

Quadrant III includes apps that have high churn and infrequent use. People install these apps for a certain purpose and then delete them later on. Travel apps fall into this category on both platforms.

An example of this quadrant are city guide apps that people download before trips to new places. Once they return home and the app has no purpose, it gets deleted.

Low Interaction Levels but Loyal User Base

Quadrant IV includes apps that have low frequency of use, but a loyal user base. These apps include reader apps for magazines and newspapers. While a user may not check them everyday, they’re unlikely to switch the newspaper they read.

This leads to loyal users over years with regular, but not everyday use.

Make a Card Game with Our Open-Source Example

So you’re ready to get in on the gold rush? Read on to find out how you can launch your own highly lucrative card game today.

One Card! – Mobile Card Game Example

One Card! is a 4-player card game you can play against real opponents or as a single player. The game was first released to showcase V-Play’s Multiplayer component, and it’s proven to be a big success in it’s own right. With little-to-no marketing, the game has gained over 200,000 players. Since its release, we’ve noticed strong user retention and high frequency metrics within the game, exactly as Flurry described.

screen520x924
The secret behind these strong metrics is the V-Play Multiplayer component. This component adds a wide range of features to the game, which make it perfect for retaining users.

V-Play Multiplayer adds leaderboards for high scores, a social system for adding friends, in-game chat, a messaging service and an intelligent matchmaking service for creating or joining games.

It’s the combination of social features like in-game chat and the friend system with advanced matchmaking options that keep players coming back.The social features keep players interested because it’s an easy way for them to play with their friends. And the advanced matchmaking features mean that even when their friends aren’t around, they’ll still have real players to play against.

In fact, the matchmaking features of the V-Play Multiplayer component allow players to join a game at any time. Players can create a game and invite their friends to join in via Push Notification. And they in turn can join games that they’ve been invited to – even when the game has already begun. V-Play Multiplayer supports this late-join feature and it is one of the success drivers in the Once Card game.

One Card! Also features global leaderboards and friend leaderboards so players can keep track of their achievements and progress in the game. These features can be added to any V-Play game in just a few minutes thanks to the V-Play Game Network component.

You can watch a short trailer for the game and its multiplayer features here:

You can access and change this open-source game example in any way you like, once you download V-Play.

V-Play is a free cross-platform development tool that has been ranked above Unity, Corona and many more for ease-of-use, time-savings and customer satisfaction. Sign-up is free and includes access to our entire range of open-source app and game examples. We have example apps and games for side-scrollers, platformers, map apps, messaging apps and more. You can see all the app & game examples in our online documentation!

Once you download the SDK, there are a few different ways to access the card game example. First, you can select it from the examples view in Qt Creator. You can also find it in the V-Play Sample Launcher or you can launch it from your installation directory. You can learn how to do that here!
onecard-menuonecard-game

Download Free One Card! Source Code

Enter the highly lucrative mobile card game genre today and start building your loyal user base now!

Of course, if you want to try One Card! before you download V-Play, you can find it in the App Store and Google Play.

Tell Your Friends!

Don’t keep this secret to yourself, tell your friends. You can like this article on Facebook using the button on the left. For more articles like this, sign-up for V-Play and you’ll get it in your inbox when it is released. It has information on a range of topics from user acquisition to free tools for making pixel art, plus news on all the latest V-Play updates and features.

Hope you liked the article, make sure to check back soon for more informative posts on mobile app and game development!

More Posts Like This

16 Sites Featuring Free Game Graphics for Game Developers

game graphics

How to Quickly Make a Flappy Bird Game

Flappy Bird

How to Make a Game like Super Mario Maker with Our New Platformer Level Editor

super mario level editor blog

Release 2.9.0: V-Play Multiplayer Launch

multiplayer

The post Mobile Card Games: How to Make the Most of User Retention & Loyalty appeared first on V-Play Engine.

Qt Together with Telechips

We are happy to announce the new collaboration between The Qt Company and Telechips. Telechips (http://www.telechips.com) is a leading fabless semiconductor company in Asia focusing on automotive and consumer electronics industries, where Qt has been used as a core component for a wide variety of innovative products.

Cooperation between The Qt Company and the SoC company based in South Korea brings great synergy. Working together, we are able to provide users and customers with an impressive toolset which features Telechips hardware with the latest Qt libraries and Qt Creator integration. This enables customers to begin software development and deliver immediate results. This provides cost-efficiencies that set a solid foundation and prove the value of Qt in each multiple industries. This is the first step for making a great partnership.

telechips-tcc8971-and-qt-creator

Figure 1. Deployment on Telechips TCC8971 from Qt Creator

The board was connected to the laptop via USB interface and the target of deployment was set to the custom device in Qt Creator – as you can see in the above picture. The Qt application was cross-compiled and deployed from Qt Creator in the same manner as the supported platforms of Boot to Qt (http://doc.qt.io/QtForDeviceCreation/qtee-supported-platforms.html).

Telechips already provides a nice Linux distribution based on Yocto for their devices. So we were able to build up Qt demo launcher and Qt Creator integration was provided out-of-the-box. Now we can build a system image with the latest Qt version and deploy a Qt application from Qt Creator to a device directly with just a few clicks. It means it would be perfectly possible to keep on using up-to-date Qt libraries on the hardware and evaluate other offerings such as Qt Automotive Suite (http://www.qt.io/qt-automotive-suite/).

Currently you need to build the image by yourself with our support, but we expect it will be possible to deliver complete build recipes in the near future. Please stay tuned for update about upcoming steps with Telechips.

For further details, please contact South Korea office of The Qt Company.

The post Qt Together with Telechips appeared first on Qt Blog.

Movin' on...

A year has gone by since I started work with Canonical. As it turns out, I must be on my way. Where to? Not real sure at this moment, there seems plenty of companies using Qt & QML these days. \0/


But saying that, I am open to suggestions. LinkedIn
 
Plenty of IoT and devices using sensors around. Heck, even Moto Z phone has some great uses for sensor gestures similar to what I wrote for QtSensors while I was at Nokia.

But a lack of companies that allow freelance or remote work. The last few years I have worked remotely doing work for Jolla and Canonical. Both fantastic companies to work for, which really have it together for working remotely.

I am still surprised that only a handful of companies regularly allow remote work. I do not miss the stuffy non window opening offices and the long daily commute, which sometimes means riding a motorcycle through hail! (I do not suggest this for anyone)

Of course, I am still maintainer for QtSensors, QtSystemInfo for the Qt Project, and Sensor Framework for Mer, and always dreaming up new ways to use sensors. Still keeping tabs on QtNetwork bearer classes.

Although I had to send back the Canonical devices, I still have Ubuntu on my Nexus 4. I still have my Jolla phones and tablet.

That said, I still have this blog here, and besides spending my time looking for a new programming gig, I am (always) preparing to release a new album. http://llornkcor.com
and always willing to work with anyone needing music/audio/soundtrack work.

Qt Everywhere at CES 2017

Experience the latest development in connected devices & powerful cross-platform applications in our meeting suite and CES, the world’s leading consumer electronics event in dazzling Las Vegas show front. Come see our demos, visit the industry leaders showing Qt, and book a meeting with the Qt executives to discuss your product strategy.

Interact with innovative demonstrations at the Westgate Meeting suite #2010:

  • Future Multiscreen UI – Qt Automotive Suite
    Research different UI concepts in vehicle instrument clusters and IVI systems to integrate different Qt technologies relevant especially to the automotive industry.
  •  IVI & Application Store Implementation – Qt Automotive Suite
    Streamline reference UI designs for IVI systems including multiple IVI applications and application store development.
  • Boot-time Optimization
    Boot up your project in 1.2 seconds with Qt and Toradex Apalis i.MX6 Computer on Modules
  • Qt on Android Wear
    Easily Kickstart Qt for wearables with Qt 5.7
  • Qt Lite Project for IoT
    Faster, smaller and more impressive Qt than ever made for IoT system development.

Visit the industry leaders on the show floor:

  • LG – WebOS TV platform devices and Vehicle Component (VC) built with Qt, LVCC North Hall Upper level meeting rooms
  • Formlabs – Advanced connected 3D printers built with Qt, Tech West, Sans Expo Center, Booth #43215
  • Delphi – IVI system based on Qt 5.5 built with Qt, LVCC North Plaza
  • HARMAN – Automated UI Development Suite built with Qt, Hard Rock Hotel, 4th floor private meeting rooms, and GENIVI Showcase on Thursday, January 5 at the Bellagio
  • BlackBerry QNX – Qt-based system using QNX Platform for Infotainment, LVCC North Hall #7029
  • AGL – In-Vehicle Infotainment (IVI) system, GENIVI Showcase on Thursday January 5 at the Bellagio

Schedule a visit to meet with Qt executives at the Westgate, Suite #2010, from January 5-8, 2017 at CES.

 

The post Qt Everywhere at CES 2017 appeared first on Qt Blog.

Cutelyst 1.2.0 released

Cutelyst the C++/Qt web framework has a new release.

  • Test coverage got some additions to avoid breaks in future.
  • Responses without content-length (chunked or close) are now handled properly.
  • StatusMessage plugin got new methods easier to use and has the first deprecated API too.
  • Engine class now has a struct with the request subclass should create, benchmarks showed this as a micro optimization but I've heard function with many arguments (as it was before) are bad on ARM so I guess this is the first optimization for ARM :)
  • Chained dispatcher finally got a performance improvement, I didn't benchmark it but it should be much faster now.
  • Increased the usage of lambdas when the called function was small/simple, for some reason they reduce the library size so I guess it's a good thing...
  • Sql helper classes can now use QThread::objectName() which has the worker thread id as it's name so writing thread safe code is easier.
  • WSGI got static-map and static-map2 options both work the same way as in uWSGI allowing you to serve static files without the need of uWSGI or a webserver.
  • WSGI got both auto-reload and touch-reload implemented, which help a lot on the development process.
  • Request::addressString() was added to make it easier to get the string representation of the client IP also removing the IPv6 prefix if IPv4 conversion succeeds.
  • Grantlee::View now exposes the Grantlee::Engine pointer so one can add filters to it (usefull for i18n)
  • Context got a locale() method to help dealing with translations
  • Cutelyst::Core got ~25k smaller
  • Some other small bug fixes and optimizations....

For 1.3.0 I hope WSGI module can deal with FastCGI and/or uwsgi protocols, as well as helper methods to deal with i18n. But a CMlyst release might come first :)

Enjoy https://github.com/cutelyst/cutelyst/archive/r1.2.0.tar.gz

Summary of 2016

So, 2016 has been a great year to me. Interesting in many aspects, but most has turned out to be for the better. I’ve gotten to know a bunch of awesome new people, I spoken about open source, Qt and Linux in Europe and USA, I’ve helped hosting an open source conference in Gothenburg, I’ve learned so much more professionally and as a person, and I’ve really enjoyed myself the whole time.

2016 was the year that…

  • … myself and Jürgen where Qt Champions for our work with the qmlbook. It feels really great getting recognition for this work. I really want to take QML Book further – during 2016 both myself and Jürgen have been too busy to do a good job improving and extending the text.
  • … I had to opportunity to visit the Americas (Oregon and California) for the first time in my life. Felt really nice having been on another continent. Now it is only Africa and Australia left on the list :-)

  • … I picked up running and has run every week throughout the year, averaging almost 10km per week. This is the first year since we built out house and had kids (so 11 or 12 years) that I’ve maintained a training regime over a full year.
  • foss-gbg went from a small user group of 15-30 people meeting every month to something much larger. On May 26 the first foss-north took place. This is something some friends of mine and myself have discussed for years and when we finally dared to try it was a great success. We filled the venue with 110 guests and ten speakers and had a great day in the sunshine. In the events after foss-north, the local group, foss-gbg has attracted 40-60 people per meeting, so double the crowd.

  • Pelagicore, the start-up I joined in 2010 when we were only 6 employees, was acquired by Luxoft. We had grown to 50+ employees in the mean time and put Qt, Linux and open source on the automotive map. It has been a great journey and I feel that we being a part of something bigger lets us reach even further, so I’m really excited about this.

2017 will be the year that…

  • … I make more time for writing – on qmlbook, this blog and more.
  • … I improve my running and increase my average distance per run as well as distance per week.
  • foss-north will take place again. This time with double the audience and dual tracks for parts of the day. I will share more information as it develops. This time, the date to aim for is April 26. In the mean time, foss-gbg will have fewer, but larger, meetings.
  • … Qt, Linux and open source becomes the natural choice in automotive. I will do my best to help this turn out true!

Even as 2016 has been really good, I hope that 2017 will be even greater. I’m really looking forward to learning!

Qt 5.8.0 Release Candidate Available

Qt 5.8.0 Release Candidate is now available!

The target is to release the official Qt 5.8.0 release during January 2017 so please try the RC now. All feedback is welcome! Please report new bugs to bugreports.qt.io. You can also send e-mail to Qt Project mailing lists or contact us via IRC.

More information about the upcoming Qt 5.8.0 release can be found on the  Qt 5.8.0 new features page, Qt 5.8 Beta blog post and from Qt Documentation snapshots.

You can update Qt 5.8.0 RC in your existing online installation by using the maintenance tool. You can also download new installers (online or offline) from the Qt Account (for commercial users) or from download.qt.io.

The post Qt 5.8.0 Release Candidate Available appeared first on Qt Blog.

KDAB adds five new trainings in 2017

We’re adding an exciting raft of new trainings to our schedule for 2017 and some new locations, including San Francisco, Seoul and Beijing.

Throughout the year you will be able to sign up for top class, always-up-to-date, original-authored trainings, presented by fully qualified KDAB trainers, all engineers actively involved in delivering KDAB’s high quality projects. Here’s what others are saying about our trainings.

As well as the latest updates in Qt, C++, OpenGL, Debugging and Profiling, CMake and all the topics you expect from us, we also offer the following brand new trainings from KDAB experts:

  • Qt Automotive Suite
  • Qt for Automotive Development
  • Introduction to C++
  • Qt 3D
  • User-Centred Development and Usability

Sign up now!

The post KDAB adds five new trainings in 2017 appeared first on KDAB.

Qt Automotive Suite video

KDAB’s experience with using Qt in the motor industry has shown us that a specifically tailored automotive Qt solution would be very valuable. So, with our partners The Qt Company and Pelagicore we created the Qt Automotive Suite, a comprehensive solution with a licensing model specifically designed for the automotive industry.

Read a more in-depth view of the Qt Automotive Suite…

The post Qt Automotive Suite video appeared first on KDAB.

How to Make Cross-Platform Mobile Apps with Qt – V-Play Apps

2016 was a big year for V-Play Apps. After its initial release in August 2015, the V-Play Apps SDK has been improved tremendously. We’ve added a lot of features to the tool this year and made even more open-source example apps available to V-Play developers. To celebrate this, we’ve produced a short video to help you find out what V-Play Apps is all about!

Check it out to find out why V-Play Apps should be your first choice when it comes to cross-platform development!

What is V-Play Apps?

Build Your App with QML & JavaScript

V-Play Apps is a tool for creating cross-platform apps using QML and JavaScript. QML is a rapid development language that’s easy to learn, and perfect for making feature rich, animated UIs. JavaScript is used to control your app’s logic.

Create Truly Cross-Platform Mobile Applications

Mobile apps created with V-Play Apps have a single code base. You can use the same source code to deploy your app to Android, iOS and other platforms. And because all V-Play Apps feature responsive-design as standard, your apps will have a native look and feel on all platforms.

native-navigation-ios-and-android

Develop for Free or Upgrade for Advanced Features & Support

You can develop and release your mobile app with V-Play Apps for free. For advanced support, training and features, you can sign up for V-Play Indie on a monthly or yearly basis. For an all-inclusive package and early access to new V-Play features, you can evaluate V-Play Enterprise.

platforms_black

See our pricing page or get in touch for all the options. We’re happy to help!

How Does V-Play Apps Work?

V-Play & Qt

V-Play Apps is based on Qt, the framework behind popular applications such as Skype, VLC Player and Autodesk Maya. There are over 1 million active Qt developers in the world today, with more on the way.

theqtcompany_logo_1200x630
You can develop your V-Play Apps using the Qt Creator IDE. This free IDE is included when you download V-Play and features code completion, debugging and profiling and an integrated UI Designer.

Qt development with V-Play presents mobile app developers with a whole new world of possibilities. V-Play Apps comes with ready-made Qt components for sensors, advanced connectivity options, multimedia and HTML5 content, shader effects, and much more.

Emulate Different Mobile Platforms As You Develop

V-Play Apps allows you to emulate different platforms while developing on your desktop. With our platform emulation feature, you can see what your app will look like on an iPhone 4 or a Nexus tablet instantly. Visual components automatically change their style, depending on your target platform.

Get Responsive Design On All Devices

You can also switch between different resolutions during development builds to see how your app or game will appear on different devices. This makes testing much easier as you don’t need to deploy your app or game to real devices to see what it will look like on an iPhone or a Nexus tablet.

With built in support for responsive design, you can achieve pixel perfect layouts on any device, including tablets or embedded systems. V-Play Apps even works on in-vehicle computers, in-flight entertainment systems, smart home devices and more.

Enjoy Native Look & Feel On All Platforms

V-Play Apps run fully native on devices without using any wrapper or hybrid methods. Our auto-adjusting UI elements can change from being a navigation drawer on Android device to being a tab on your iPhone. This means your users can enjoy a native look & feel while using your app.

Access to Camera, Sensors, File System and many more native device features also work as intended.

What Are the Benefits of V-Play Apps?

Ease of Use, Time Savings & Customer Satisfaction

The main benefits of V-Play Apps are its ease of use and time savings. In fact, V-Play has been ranked higher than Xamarin, PhoneGap, Unity, Corona and others as the easiest-to-use cross-platform tool with the most time-savings and most satisfied customers..

It’s the component-based approach that makes V-Play so easy to learn and implement. In some cases, mobile apps created with V-Play had 10x less code than apps created with other frameworks. These code reductions mean less bugs to fix and more time to concentrate on testing and improving your app before release.

It also means you can go from developing an app in weeks and months to making a complete app in just a few days.

And if you ever need some extra help or have a feature request, you can get in touch with our highly-rated support team. Drop us a line at support@v-play.net if you have any questions!

V-Play Plugins

If you want to include advertising, analytic tools or other services in your app, you can save even more time by choosing from our wide range of V-Play Plugins. You can monetize your app with native in-app purchases and multiple ad networks with rewarded videos, interstitials or banner ads.

You can use the Google Analytics plugins to gain insights on user behaviour within your app. Or you can send push notifications or add social features to engage your users with ease. It will take you less than 10 minutes to integrate these plugins, using only 10 lines of code, which then works cross-platform.

plugin-overview

Here’s a quick example of how you can add the OneSignal plugin to your V-Play App and send a simple push notification:


import QtQuick 2.0
import QtQuick.Controls 2.0
import VPlayPlugins 2.0

ApplicationWindow {

  OneSignal {
    appId: ""
    onNotificationReceived: {
      console.debug("Received push: ", message)
    }
  }
}

To see an example of how easy it is to add V-Play Plugins to your V-Play App, check out our quick guide here.

Extendable Code

If you have existing native code or if you want to use a 3rd party SDK, you can extend V-Play Apps with C++, Java or Objective C code without any limits.

What Else Should I Know About V-Play Apps?

Open Source App Examples

V-Play Apps comes with a selection of open-source app examples. These app examples can be used as the basis for your own app and can be changed in any way you like.

For example, you can adapt a Twitter Viewer app created with V-Play, in just 700 lines of code. It connects with the Twitter REST API and includes advanced animations and native navigation on all platforms – you can use this open-source code for free in your own app!

The easiest way to view these app examples is with the V-Play Sample Launcher. This standalone application offers access to all of V-Play’s app examples. You can download it for free here!

You can also access these app examples directly from the SDK. Navigate to <Path to your V-PlaySDK>/Examples/V-Play>in your V-Play installation. Just open the .pro files with Qt Creator and you can run the demos on your development PC or deploy them to your mobile devices.

V-Play Apps Showcase App

You can get a quick overview of the power of V-Play Apps by downloading our Qt 5 Showcases app from the App Store or Google Play.

google_play_badge-1  itunes_download_link

This Qt 5 Showcases App contains multiple application samples developed with V-Play Apps. It shows developers and designers how V-Play Apps is used to create mobile apps with native user experience (UX) and fluid UI animations.

Download V-Play Apps for Free

Get your free V-Play Apps download now and start making your cross-platform mobile app!

Download V-Play Apps Now!

If you’re completely new to Qt and mobile development, you can take a look at our Getting Started guide for help!

More Posts like This

20 Free & Secure Alternatives to the Parse Push Service

parse-plugin

The 13 Best Qt, QML & V-Play Tutorials and Resources for Beginners

tutorials capture

21 Tips That Will Improve Your User Acquisition Strategy

User Acquisition

7 Useful Tips That Will Improve Your App Store Optimization

User Acquisition

The post How to Make Cross-Platform Mobile Apps with Qt – V-Play Apps appeared first on V-Play Engine.

Qt Champions for 2016

Qt Champions

It is the time of the year when we take a look back and see who have been the Qt Champions this year.

First I would like to point out that all the people nominated are all incredible!

Let’s take a quick look at all the nominees:

  • JKSH – a long time Qt developer, who shows up almost everywhere where you look. And I do mean everywhere, take any Qt online service we have and he can be found there. Maybe not the first person you run into, but always there helping people with Qt.
  • kshegunov – a newer face in the Qt Community, but has already made an impact. Has contributions into Qt during his first year as a community active. You can also find him in the C++ Gurus section of the Qt Forums answering and sometimes asking hard questions.
  • Ekke – with a strong background in BlackBerry development, Ekke has moved to full time to the Qt community recently. He has a running blog post series on Qt for mobile development and he made the event applications for both QtCon and Qt World Summit this year. As a long time developer he has provided the developers of Qt Quick Controls 2 with a lot of feedback and ideas.
  • BenLau – another long time Qt developer. He has done a lot with Qt, and got some mentions from the developers of QML too. You can find Ben in many places, also the QtMob slack group, where Qt mobile developers gather nowadays. Take a peek at Bens github page to see a nice green wall.
  • mrjj – is a familiar name to anyone on the Qt Forum. Among the top three active contributors on the Qt Forum and especially this year he has been incredibly helpful and active.
  • VoidRealms – 155 Qt videos on YouTube and counting. And 155 code examples to go with those 155 videos. Also a bunch of projects and other code examples in Qt and multiple other languages too. He has been working with Qt for a long time and still releases videos at a steady pace.

As a short reminder, Qt Champions  are people who go the extra mile for the Qt community. They help out newcomers and make the community a welcoming and friendly place for everyone. The categories for Qt Champion nominations go as follows:

  • Community Builder – helping the Qt community
  • Ambassador – making Qt known
  • Content Creator – creating and sharing original Qt content
  • Maverick – significant and surprising contributions
  • Rookie of the Year – best first contribution to the Qt codebase

In light of the sheer skill and persistence of all the nominees, I find it hard to do anything else than award all the nominees the title of Qt Champion 2016.

The categories for our new Qt Champions go as follows:

  • Community Builder: JKSH and mrjj
  • Ambassador: Ekke
  • Content Creator: VoidRealms
  • Maverick: Benlau
  • Rookie of the Year: kshegunov

Please join me in congratulating the new Qt Champions!

The post Qt Champions for 2016 appeared first on Qt Blog.

Fixing bugs via lateral thinking

For today’s blog I would like to share with you the little adventure I had when fixing a very strange bug in Qt.

Pop quiz

Don’t think about this too much, just guess: what does this QML snippet print?

import QtQuick 2.0

QtObject {
    Component.onCompleted: {
        console.log("240000000000" == "3776798720");
    }
}

There are no JavaScript semantic tricks involved; and using either == or === does not change the result in any way.

Did you get it?

Pop quiz (2)

Here’s another one, this time in pure C++: what does this print?

     QJSEngine engine;
     QJSValue value("foo");

     QJSValue obj = engine.newObject();
     obj.setProperty("240000000000", value);

     QJSValueIterator it(obj);
     while (it.hasNext()) {
         it.next();
         qDebug() << it.name() << it.value().toString();
     }

Right now you should be suspicious of that strange value…

Ready for it?

Solution

In Qt 5.6.2 and Qt 5.7.0 the QML test prints "true"! According to QML the two strings "240000000000" and "3776798720" are totally identical.

Moreover, the C++ test prints "3776798720" "foo", not "240000000000" "foo" as one could’ve imagined.

So, what is going on? Who told me to use JavaScript again?

The bug

This bug against the JavaScript engine of QML (internally called V4) was reported on Qt’s bugtracker a few days ago, and quickly gained a lot of votes (probably because it was also cross-posted to Stack Overflow).

So, what do we have here? A very popular bug report, with no assigner set, and myself who has been wanting for a while to peek into the internals of the V4 JavaScript engine… well, let’s go!

Analysis

Where do you start looking around in a codebase you’re totally unfamiliar with? The first step I took was trying to understand what values made the engine misbehave. Note that the reporter was very clever at noticing something strange with the values:

240000000000 == 0x37E11D6000
3776798720   ==   0xE11D6000

By the way, “240000000000” isn’t the only value failing — “240000000001” misbehaves too (returning “3776798721”).

So maybe I needed to look for some bit pattern. “Maybe Qt is storing these strings as 64 bit integers, and using the top bits to store some additional metadata, and the integer gets corrupted somehow”, I thought.

Then I wondered: is any big number (represented as a string) problematic? No, “300000000000” works, and “200000000000” works too.

Maybe it’s a range somewhere between those two extremes?

With a very quick binary search (using Perl to generate and run QML testcases), in a few steps I was able to determine the exact range that make everything fail: any string between “238609294222” and “249108103166” inclusive. Values before and after those two worked perfectly. Do these numbers share some bit pattern?

238609294221 == 0x378E38E38D   // biggest working before the problematic range
238609294222 == 0x378E38E38E   // smallest not working
249108103166 == 0x39FFFFFFFE   // biggest not working
249108103166 == 0x39FFFFFFFF   // smallest working after the problematic range 

Uhm, I can’t spot any bit pattern in there that could cause this. Indeed, this turned out to be a complete red herring.

Debugging through V4’s code

Of course, the next step is to try to step into the JavaScript engine and see if something is wrong. That turned out to be … problematic.

A JavaScript engine is not a trivial piece of code; there’s a lot of dark magic in there to give JavaScript semantics to values, and keep them allocated in efficient ways.

Most of the time, the debugger was not able to print any local whatsoever (even in a -O0 -g build), and when it was, the locals were totally meaningless, as I was probably in memory that was getting happily reinterpret_cast()ed across different internal datatypes. So, I simply was not able to understand at all which paths the code was going through (and why) in order to determine which one(s) could be problematic.

I realized that I needed a more structured approach at trying to find where the code paths diverged. That is (light bulb moment), I needed a way to trace the function calls and diff them. One way could’ve been: add printfs everywhere. Or: launch multiple debugging sessions, over different testdata, and advanced them in parallel to check where executions diverge.

But, in both cases, step by step would be a huge task, given the hundreds if not thousands of nested calls into the engine for something as trivial as setting a string property. We can do better by instrumenting the binaries and getting the traces generated for us.

Function tracing

There’s a ridiculously simple way to get traces for every function call: recompile your libraries/applications with -pg. If you also pass -O0, -g and other options that prevent the compiler from being too smart, you can gather extra useful data for each function call, such as the arguments passed to the functions, and the values returned.

It turns out that Qt’s configure script natively supports the -pg option via the -profile switch, so I simply recompiled both qtbase and qtdeclarative with it.

And now, the C++ testcase above generates accurate tracing data. How could I use them? I went for the simplest approach possible: let’s do a visual comparison.

Thanks to the awesome uftrace tool one can dump the C++ testcase’s trace straight into Chromium’s tracing flamegraph. There it is:

Visualization of C++ fucntion call traces into chromium.

Visualization of C++ function call traces into Chromium.

The trace in the top half is a working testcase, the one below a broken case.

Now the difference in behavior is quite evident!

In the broken case, QV4::Object::putIndexes gets called, instead of QV4::Object::put. Great! That was the hint I needed. From there on, it was kind of downhill.

Narrowing down the analysis

The point of divergence looked like this:

     ScopedString s(scope, engine->newString(name));
     uint idx = s->asArrayIndex();
     if (idx < UINT_MAX) {
         setProperty(idx, value); 
         return;
     }
     s->makeIdentifier(scope.engine);
     QV4::ScopedValue v(scope, QJSValuePrivate::convertedToValue(engine, value));
     o->put(s, v);

The idx < UINT_MAX check passes in the broken case, resulting in the indexed setProperty call (which in turn calls putIndexed), rather than the call to o->put at the end.

So what is that s->asArrayIndex() call anyhow? Well, my suspicion is that it’s an (important) optimization for accessing an object, using strings representing base-10 integers as keys. Arrays in JavaScript are objects that are indeed accessed this way (i.e. all arrays are actually associative arrays). So the engine tries to see if the string “looks like an integer”, and if so, uses some specialized storage (in a sparse array structure rather than a map).

But “240000000000” is an integer indeed, so what’s going on here?

asArrayIndex does this:

     uint asArrayIndex() const {
         if (subtype() == Heap::String::StringType_Unknown)
             d()->createHashValue();
         Q_ASSERT(!d()->largestSubLength);
         if (subtype() == Heap::String::StringType_ArrayIndex)
             return d()->stringHash;
         return UINT_MAX;
      }

I still have no clue about what those subtypes are, but I could spot the call to createHashValue() from the trace, therefore I knew it was getting called, therefore the string type was Unknown.

So, time to go back to a debugger, and check what value was calculated there — and that’s indeed the broken 3776798720 value.

What does createHashValue() do? It calls toArrayIndex, which calculates a “hash” for the string, and possibly changes its subtype (if it detects that it is a valid index).

And that’s the culprit. The function has the bug just sitting there:

         uint n = i*10 + x;
         if (n < i)
             // overflow
             return UINT_MAX;

That’s not a valid overflow check for multiplication. (It’s actually the check for detecting unsigned integer overflow for an addition.) That failing check was making the engine think it could treat such a big number as a 32-bit unsigned integer index into a sparse array. So, fix that, and job done!

Conclusions

It’s always rewarding to come up with the right idea at the right time to solve a very complex problem :).

In the meanwhile, the fix for this very strange bug has been submitted to Qt here, and it’s already merged in qtdeclarative (commit). The fix will be released in some future version of Qt; until then, talk to our consulting services if you need this issue fixed earlier.

In the meanwhile, happy hacking!

About KDAB

KDAB is a consulting company offering a wide variety of expert services in Qt, C++ and 3D/OpenGL and providing training courses in:

KDAB believes that it is critical for our business to contribute to the Qt framework and C++ thinking, to keep pushing these technologies forward to ensure they remain competitive.

The post Fixing bugs via lateral thinking appeared first on KDAB.

Embedded Devices with Qt and the INTEGRITY RTOS

by Rolland Dudemaine, Green Hills Software (Qt Blog)

The Green Hills INTEGRITY Real-Time Operating System (RTOS) is widely used in safety- and security-critical systems. Work has been ongoing for already some time to get Qt 5 running on INTEGRITY, and now we are delighted to show a proof-of-concept port of Qt 5.7 on top of INTEGRITY.

Qt 4.8 support has been available for a long time on the INTEGRITY RTOS. We are now pleased to announce that a proof-of-concept port of Qt 5.7 to INTEGRITY has been completed by Green Hills engineers. During the work, we tested the port on all major embedded HW platforms, including ones that have OpenGL ES support available. Work continues together with The Qt Company and the Qt ecosystem and thanks to this initial prototype, the upcoming Qt 5.9 is expected to contain INTEGRITY support.

In the automotive space where both Qt and the INTEGRITY RTOS are already present, this allows for additional synergies where Qt can be used in conjunction with INTEGRITY on both infotainment systems as well as instrument clusters. Especially in automotive instrument clusters as well as in other safety critical systems the certified RTOS is a vital building block.

In the prototype Qt integration we built all the basic libraries one expects: Core, Network, Gui, Svg, XmlPatterns, ImageFormats, Widgets. Applications can also take advantage of the more modern part of the framework, including Qt Quick 2, Qt Quick Controls 2, and Qt 3D.

The following video presents a Qt cluster running on the proof-of-concept port of Qt 5.7 on INTEGRITY 11.4.4 on NXP i.MX6.

The proof-of-concept port has been so far been used on NXP i.MX6, Intel Apollo Lake, TI Sitara and Jacinto 6. Other platforms like Renesas R-Car H3 are expected to come very soon too. We are also strongly cooperating with partners from the Qt ecosystem who can help customers get to production faster with the integrated solution.

The post Embedded Devices with Qt and the INTEGRITY RTOS appeared first on Qt Blog.

Eliminate Technical Risks in Your Software Project

The Qt framework contains very powerful libraries that help to create great products that provide modern user experiences. At the same time, Qt is versatile and can be used across multiple purposes which offers many options and increases flexibility – but these can also be puzzling if one is not familiar with Qt.

Meeting your time-to-market targets on-time is essential and a key component in defining your success. One of the most important things in a software project is to eliminate risks, especially technical risks in this case, that can hinder reaching the product requirements and jeopardize the project schedule.

Nowadays, customer expectations are based on usability experiences from modern smartphones and tablets, where ease-of-use and smooth operations are fundamental. At the same time, bill of material (BOM) is playing its part of this equation meaning that the most efficient chipsets are rarely used but you need to maximise benefits of the software framework.

Meeting Your Performance Targets

The most common request to The Qt Company Services is to help with the performance. Typically, we in the Qt Consulting team receive that type of request when the feature complete milestone has already passed, and the customer has invested a lot of money into development. Unfortunately, quite often we see that there have been mistakes made early on in the project with the architecture solution for example. This can happen if Qt is not used efficiently which can hinder the achievement of your product requirements or specifications causing expensive refactoring.

We are happy to help with advising customers on planning and designing the product. We provide the best value for our customers in an architecture workshop which gives guidance and points you into the right direction from Day One.

Some customers building with proof of concept (POC), and this can be challenging if there is a gap in Qt know-how. Our experts can build customer use cases for different platforms typically within a week or two, and we have a wide range of ready-made demos in different HW which provide good benchmarking for the customer to make the right decisions.

For more information on Qt Consulting Services, please contact sales@qt.io

The post Eliminate Technical Risks in Your Software Project appeared first on Qt Blog.

QtCon Videos On-line

We’re delighted all the QtCon talks have now been released, thanks to the hard work of the folks at KDE.

Many KDABians attended QtCon and contributed to the unique new Qt event we co-created in Berlin, September 2016, along with Qt Contributors, KDE Akademy, VideoLan and FSFE.

KDAB funded the event upfront and was Gold sponsor at QtCon along with The Qt Company. We also ran a training day showing our commitment to supporting not just Qt at the leading edge but also C++, OpenGL, CMake and more, at a fraction of the usual cost.

But our contribution to the program was the most notable. We contributed 11 talks, participated in the program committee and arranged the program, the overall quality of which speaks for itself.

The event itself was free, and enabled by a wide range of sponsors in addition to KDAB and The Qt Company.

Google and bluesystems at Silver, basyskom, BMW Group, froglogic, Intel and e-Gits at Bronze and openSUSE, woboq, Pelagicore, openinvention network and Ableton at Support level all helped make this outstanding event possible. Reaction has been overwhelmingly positive from community members of all the organising groups as well as the newcomers. Thanks again to all. We couldn’t have done it without you.

See the KDAB QtCon talks here.

The full program is available here.

The post QtCon Videos On-line appeared first on KDAB.

Cutelyst 1.1.2 released

Cutelyst the C++/Qt Web Framework just got a new release.

Yesterday I was going to do the 1.1.0 release, after running tests, and being happy with current state I wrote this blog post, but before I publish I went to www.cutelyst.org CMS (CMlyst) to paste the same post, and I got hit by a bug I had on 1.0.0, which at time I thought it was a bug in CMlyst, so decided to investigate and found a few other bugs with our WSGI not properly changing the current directory and not replacing the + sign with an ' ' space when parsing formdata, which was the main bug. So did the fixes tagged as 1.1.1 and today found that automatically setting Content-Length wasn't working when the View rendered nothing.

Cutelyst Core and Plugins API/ABI are stable but Cutelyst-WSGI had to have changes, I forgot to expose the needed API for it to actually be useful outside Cutelyst so this isn't a problem (nobody would be able to use it anyway). So API stability got extended to all components now.

Thanks to a KDAB video about perf I finally managed to use it and was able to detect two slow code paths in Cutelyst-WSGI.

The first and that was causing 7% overhead was due QTcpSocket emitting readyRead() signal and in the HttpParser code I was calling sender() to get the socket, turns out the sender() method implementation is not as simple as I thought it was and there is a QMutexLocker which maybe caused some thread to wait on it (not sure really), so now for each QTcpSocket there is an HttpParser class, this uses a little more memory but the code got faster. Hopefully in Qt6 the signal can have a readyRead(QIODevice *) signature.

The second was that I end up using QByteArrayMatcher to match \r\n to get request headers, perl was showing it was causing 1.2% overhead, doing some benchmarks I replaced it by a code that was faster. Using a single thread on my Intel I5 I can process 85k req/s, so things got indeed a little faster.

It got a contribution from a new developer on View::Email, which made me do a new simplemail-qt release (1.3.0), the code there still needs love regarding performance but I didn't manage to find time to improve it yet.

This new release has some new features:

  • EPoll event loop was added to Linux builds, this is supposedly to be faster than default GLib but I couldn't measure the difference properly, this is optional and requires CUTELYST_EVENT_LOOP_EPOLL=1 environment to be set.
  • ViewEmail got methods to set/get authentication method and connection type
  • WSGI: can now set TCP_NODELAY, TCP KEEPALIVE, SO_SNDBUF and SO_RCVBUF on command line, these use the same name as in uwsgi
  • Documentation was improved a bit and can be generated now with make docs, which doesn't require me to changing Cutelyst version manually anymore

And also some important bug fixes:

  • Lazy evaluation of Request methods was broken on 1.0.0
  • WSGI: Fixed loading configs and parsing command line option

Download https://github.com/cutelyst/cutelyst/archive/r1.1.2.tar.gz and have fun!