Skip to content

How to Profile QtQuick applications on Freescale i.MX 6 with vAnalyzer

Quick overview of profiling tools

QtQuick is often used to create UIs for embedded devices. One SoC that is quite popular at the moment is the i.MX 6 board from Freescale, with its Vivante GC2000 or GC880 3D GPU. Performance on such a device matters, users expect a fluid interaction. With the QML Profiler, Qt provides an excellent tool to dig into the performance of QtQuick applications. In cases where that is not enough and more details about graphics performance is needed, the apitrace tool provides profiling on the level of OpenGL calls. Sometimes, even more details can be useful. In this blog post, we will look at one of the tools provided by Vivante that provide GPU statistics for profiling.


Vivante provides a set of tools in their Vivante Tool Kit (VTK). It contains a shader compiler (vCompiler), an OpenGL emulator library (vEmulator), a shader development tool (vShader), a texture compression/decompression tool (vTexture), a tool to record and replay OpenGL traces, like apitrace (vTracer and vPlayer) and finally a tool to display GPU statistics, vAnalyzer. We will look at the last one, vAnalyzer, here. The download of VTK is a bit hidden and behind a registration wall, and can be found on, in the download section of the i.MX 6 product page, for example i.MX 6D/Q/DL/S/SX GPU Tools-5.0.11P4.1 for the BSP with the 3.10.53 kernel.


Recording GPU statistics can be done with vProfile, which is built into the user-space and kernel drivers. An option in the kernel controls whether profiling is compiled into the Vivante GPU kernel module. This is enabled by default in Yocto “Fido” (and probably also in earlier versions), which uses the linux-imx kernel tree. If you use another kernel, enable the VIVANTE_PROFILER option in either drivers/mxc/gpu-viv/Kbuild or in drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h. In addition, profiling needs to be enabled in the kernel command line, which also provides an option to check if profiling was compiled in. These options are galcore.gpuProfiler=1 and galcore.showArgs=1. If everything worked, something like the following should be shown during the boot process:

Galcore version
Galcore options:
  irqLine = 41
  registerMemBase = 0x00130000
  registerMemSize = 0x00004000
  irqLine2D = 42
  registerMemBase2D = 0x00134000
  registerMemSize2D = 0x00004000
  irqLineVG = 43
  registerMemBaseVG = 0x02204000
  registerMemSizeVG = 0x00004000
  contiguousSize = 134217728
  contiguousBase = 0x3CB00000
  bankSize = 0x00000000
  fastClear = -1
  compression = -1
  signal = 48
  powerManagement = 0
  baseAddress = 0x00000000
  physSize = 0x00000000
  logFileSize = 0 KB
  recovery = 1
  stuckDump = 1
  gpuProfiler = 1

If the line about gpuProfiler is missing, then profiling support was disabled during compilation.


vAnalyzer is, like all other tools in the VTK, a Windows application, which is a bit unfortunate since most i.MX boards probably run Linux, and hence the developers probably run Linux on their desktop machine as well. Fortunately, it runs fine under Wine, simply running wine setup.exe will install vAnalyzer.


Obtaining a trace is easy: Before running an OpenGL program, run export VIV_PROFILE=1. Once the program has finished, the driver will write the trace into a file, for example _378_2.vpd. This file can then be opened with vAnalyzer. There are additional environment variables you can set to control the file name or restrict the recording to a certain frame number range. Moreover, an application can start/stop the recording by calling glEnable(GL_PROFILE_VIV) or glDisable(GL_PROFILE_VIV). Consult the VTK User Guide for more details.

To demonstrate, we ran the following QML file with qmlscene -platform eglfs:

import QtQuick 2.0

Item {
    id: root
    width: 1024
    height: 768

    Component {
        id: rectComponent

        Rectangle {
            id: rect
            x: Math.random() * root.width
            y: Math.random() * root.height
            width: Math.random() * root.width
            height: Math.random() * root.height
            color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random())

            NumberAnimation on rotation {
                duration: Math.random() * 1000;
                from: 0
                to: 360
                running: true
                loops: Animation.Infinite

    function createSomeRects() {
        for (var i = 0; i < 10; i++) {

    Timer {
        interval: 2000
        repeat: true
        running: true
        onTriggered: createSomeRects()

    Component.onCompleted: createSomeRects();

QtQuick Rectangles Example

QtQuick Rectangles Example

That program creates 10 rotating rectangles every 2 seconds. vAnalyzer, as pictured in the screenshot below, nicely shows that the framerate starts to drop from 60 FPS due to fill rate limitations when we approach about 110 rectangles. This is something to keep in mind when developing UIs for i.MX 6 devices - avoid overdraw as much as possible, make sure your QML files don't contain useless Rectangles that are covered by other UI elements anyway. If in doubt, check with QSG_VISUALIZE=overdraw how much overdraw your application has.

As one can see in the right-hand listview of the screenshot, there are many more statistics from different pipeline stages that help for digging into more details. The GPU utilization is always displayed as 100% though, which is probably a bug. Nevertheless there are a wealth of other useful data points available.

VAnalyzer Main Window

vAnalyzer Main Window (click to enlarge)


vProfiler and vAnalyzer are useful tools to augment profiling data from other tools. Until now, they are not well-known, as the lack of Google search results reveals. We hope that this blog post has made developers aware of vAnalyzer's existence and will maybe help them to analyze performance of their QtQuick application on an i.MX board.

Categories: KDAB Blogs / KDAB on Qt / Tooling

4 thoughts on “How to Profile QtQuick applications on Freescale i.MX 6 with vAnalyzer”

  1. Hi Thomas,

    it seems that the QML source code does not fit to the QtQuick Rectangles Example Picture. I suppose you made this screenshot mit alpha level in line 18 set to 1 instead of Math.random().
    This reaised the question with which code the
    screenshot of vAnalyzer Main Window was made. With alpha level set to 1 or Math.random() ?

    1. Thomas McGuire

      Hi Andreas,

      well spotted! To be honest, I don’t remember if the vAnalyzer screenshot was for fully opaque or for transparent rectangles.

      I do remember there was quite a dramatic performance difference between both, and I remember I was surprised by how few Rectangles the iMX.6 is able to draw.

  2. Hi Thomas, at the start of your article you mention APITrace. Could you share some info how one could approach cross-compiling it for the i.mx6 board?

    1. Thomas McGuire

      it has been a while since I tried this.

      Vivante provides their own binary version of apitrace. In the meta-fsl layer in Yocto, the gpu-viv-bin-mx6q recipe actually downloads a package from [1] that contains their apitrace.

      I remember trying to cross-compile apitrace myself once, but I don’t remember the outcome – as I said, that has been a while.

      Hope the binary package helps you!

      [1] The exact location depends on the version, when I checked it was

Leave a Reply

Your email address will not be published. Required fields are marked *