Please note as of Wednesday, August 15th, 2018 this wiki has been set to read only. If you are a TI Employee and require Edit ability please contact x0211426 from the company directory.

XgxPerf HMI

From Texas Instruments Wiki
Jump to: navigation, search

Article 1 - Developing Vector Graphics based HMIs using Inkscape, Qt and Xgxperf

This article describes how to use Vector Graphics images for creating a professional HMI toolkit with opensource tools like Inkscape and frameworks like Qt and Xgxperf. This article applies to TI products that have an ARM9/ Cortex-A8/ higher cores, and the AM18xx family of Profibus certified products.

Screen Shot of output image


Inkscape, Qt, Xgxperf, Vector Graphics, HMI, Medical

Source Code

All source code and SVG images created from Inkscape for this article are included in the XgxPerf source package at,

Why Vector Graphics ?

Vector Graphics specifications like OpenVG/ SVG allow developers to create icons and text that can then be used by view clients (like HMI products) to render in the right manner. From the OpenVG specification document - "OpenVG may be used to render scalable user interfaces, particularly for applications that wish to present users with a unique look and feel that is consistent across different screen resolutions."

Vector Graphics and Qt

Qt has supported Vector Graphics using its SVG renderer class (QSvgRenderer). This class forms the basis of other widget classes like QSvgWidget, that can then be embedded in canvases. Support for VG based animation is provided by Qt. Because of the nature of the Vector Graphics image, any animation in Vector Graphics based classes has to be performed via costly VG operations. An intermediate path is taken in this article, that describes creating a pixmap item of required size from the VG item once, and using it further for animation. This approach uses Xgxperf framework for quick development hiding the Graphics scene initialisation and benchmarking primitives.

Creating a one-time Pixmap from VG in Qt

The principle behind this approach is - QSvgWidget can render into any paint device, including a Pixmap. Thus, a Pixmap of required size is created, and the SVG is scaled (without losing quality) and rendered without any further bitmap scaling (Bitmap scaling reduces quality), as shown in below snippet.

currPixmap = new QPixmap(targetSize);
currSvgWidget->render(currPixmap, QPoint(), QRegion(), QWidget::DrawChildren);

To create a new SVG item with this approach, just include the header file qgraphicssvgnativeitem.h (part of the XgxPerf package), and create a new GraphicsItem as below. The item is then added to the GraphicsScene. Xgxperf abstracts the graphics scene creation - refer to applicationmanager.cpp in the Xgxperf source package.

QGraphicsSvgNativeItem* pChamber3;
pChamber3 = new QGraphicsSvgNativeItem(":/images/svg/boiler1.svg", QSize(100,400));

Creating VG images in Inkscape

Inkscape is a popular editor and creator tool for VG images. There are plenty of tutorials online for using Inkscape (ex. , but the key Inkscape tools used for the Automation HMI created in this article were from the Toolbox, and from the Object and Path Menu items.

Tools from the Toolbox on the left pane

- "Draw Bezier curves and straight lines" tool

- "Draw circles, ellipses and arcs" tool

- "Create rectangles and squares" tool

- "Create and edit gradients" tool

- "Create and edit text objects" tool

- "Select and transform objects" tool

Tools from the Object main menu item and the Path item were used heavily to create required shapes and gradients.

Animating VG images in Qt

VG and the VG renderers in Qt allow for animating the VG images at run-time after loading them. But, this makes User Interfaces sluggish, if the processor cannot handle the required VG operations fast enough. To compensate for this, using the above approach of the SVGNative item, it is possible to directly employ the bitmap operations after doing the required scaling the VG domain once at start. For example, "SetRotation" can be directly called on the QGraphicsItem. For this example, refer to the automation.cpp in the "automationlib" portion of xgxperf.

Rendered output example

The rendered output of the HMI using this approach, can be seen in this snapshot of a VGA portrait screen.

Screen Shot of output image

Vector Graphics support on TI Graphics Platforms

OpenVG Hardware acceleration is supported by the SGX Graphics drivers on SGX enabled SOCs. For a complete list of these SOCs, refer to the below link.

SVG support is provided by a number of frameworks including Qt. Xgxperf framework extends the SVG support for certain use-cases, as described in this article.

Article 2- Using Gradients and Masks in Qt for Industrial HMI development

As an alternative to pre-built SVG images, Qt also allows creation of dynamic gradients programmatically. This article shows how to build gradients using Qt. This can be used for simple shapes. For complex shapes, VG tools like Inkscape should be used for creating the objects.

Gradients are a critical portion of any modern 2D Graphics framework. This article describes ways of using Gradients to improve the richness of an UI application, focusing on HMI for industrial automation. The classes developed here can be extended for other purposes.

A sample screenshot of the output created by the techniques in this class is shown below.


Creating a Thermometer and other HMI components in Qt:

Source code

The source for this article can be downloaded from the below link.

Refer file - thermo.h, in xgxperf\xgxperf\automationlib\thermo.h

This class uses 2 fundamental concepts - Masks, and Gradients, to create the thermometer.

Step 1: Creation of the thermometer outline:

The below code shows, how to set a mask, to create a thermometer visual. This code needs to be a part of the resize event handler for the widget.

More information on this, is available in "" in the document section of Qt.

QRegion r1(QRect(currRect.width()/3, 0, currRect.width()/3, currRect.height()));
QRegion r2(QRect(0, currRect.height()-10,
        currRect.width(), currRect.width()), QRegion::Ellipse);
QRegion r3 = r1.united(r2);

Region "r1" creates a rectangular region that allows only the middle 1/3 of the rectangle to be visible. This forms the stem of the thermometer. Region "r2" creates the lower bulb of the thermometer. Region "r3", the final mask, is created by making an union of both r1 and r2.

With this mask, the outline of the thermometer now becomes visible.

Step 2: Creating the thermometer internals:

To draw the interval bars, and the liquid (in red color) itself, the "paintEvent" of the widget needs to be reimplemented, and painted. This can be done by the below code.

QBrush currBrush(Qt::red);
painter.fillRect(0, (1.0-currVal)*currRect.height(), currRect.width(),
        currRect.height(), currBrush);
for (int i = 0; i < currRect.height(); i += currRect.height()/10) {
    painter.drawLine(QPoint(currRect.width()/3, i), QPoint(currRect.width()/3+5, i));

Step 3: Creating the liquid gradient:

Without a gradient, any continuous solid fill lacks the visual richness that is expected out of a modern UI. Hence, a simple gradient can be implemented using the QLinearGradient approach, with the code below.

QLinearGradient fade(0, 0, currRect.width(),0);
fade.setColorAt(0, QColor(255, 0, 0, 255));
fade.setColorAt(0.5, QColor(255, 255, 255, 255));
fade.setColorAt(1, QColor(255, 0, 0, 255));
QBrush currBrush(fade);

This code creates a brush that changes from red to white in the middle, and continues to red. When this brush is used for painting, as the rendering scan progresses from top to bottom, the liquid now gets a glowing colour, with a whitish tinge in the middle, making it look more realistic.

This code has been implemented and tested on all AM/DM35/37xx parts, on different Qt versions.

The complete code for the automation HMI demo can be obtained from xgxperf at,

Using Qt's Powervr backend for display/ 3D acceleration in XgxPerf

If the TI SGX Graphics SDK (see references below for the SDK and Qt integration) is installed, Qt/embedded (not Qt/X11) can be configured to use SGX by invoking any Qt application in the below manner:

$> ./Qt_app -qws -display powervr

Qt applications can use SGX for 3 kinds of operations.

1. OpenGL ES2.0 applications, that draw 3D objects on screen (application calls 3D APIs directly)

2. Acceleration of Screen Driver (PVR2D in SGX used as a screen driver instead of ARM SW)

In the second case, the screen rendering (2D) operations are accelerated using PVR2D, that uses SGX instead of ARM. This can result in ~10% reduction in CPU utilisation, for resolutions greater than VGA. This does not need any changes to the Qt application itself.

The above 2 categories do not need a change in the application itself.

3. In order to use the SGX HW to accelerate even 2D operations, the application has to be rewritten to utilise QGLWidget (rather than QWidget). QGLWidget is documented in Qt Documentation pages. This results in acceleration typically when screen resolutions are larger than VGA.

Further Information

Xgxperf also provides benchmarking information for all supplied classes, and provides reference implementations for simple ECG display, Industrial Automation, Video surveillance, and more. Further information on Xgxperf is available at,


Graphics SDK

Graphics SDK Getting started guide -

SGX Debug with Qt

Profibus products with ARM from TI

AM18xx Profibus products -

Block diagram with SOC selection tool - for POS/ HMI