1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
/*
quick-batching.qdoc
This file is part of GammaRay, the Qt application inspection and manipulation tool.
SPDX-FileCopyrightText: 2016 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
Author: Volker Krause <volker.krause@kdab.com>
SPDX-License-Identifier: GPL-2.0-or-later
Contact KDAB at <info@kdab.com> for commercial licensing options.
*/
/*!
\example quick-batching
\title Qt Quick Batching
\brief Investiagte render performance issues due to unmerged render batches.
\ingroup examples-gammaray
This examples shows GammaRay's capabilities for analyzing \l{Qt Quick} batch rendering issues.
\section1 Problem
The example application shows two custom Qt Quick sliders consisting of flat colored rectangles
forming a gradient from green to blue. Inactive rectangles (that is rectangles above the handle)
are drawn smaller and slightly grayed out.
\snippet quick-batching/quick-batching.qml Slider setup
Observed in a OpenGL tracing tool or profiler, it can be seen however that the two sliders take
several hundred OpenGL calls to be rendered. Closer investigation shows that each rectangle results
in a separate OpenGL draw call.
\section1 Investigation
There are several aspects of this problem that can be analyzed with GammaRay.
\section2 Scene graph render diagnostic messages
The \l{Qt Quick} renderer has some built-in diagnostic messages that can sometimes be helpful in
such a scenario. Turning them on unconditionally can be inconvenient though, as they are usually
triggered by frame. It is therefore useful to only enable them for a short amount of time while
triggering the relevant operation in the target application.
This can be done using the GammaRay \l{Messages} tool. Open the Logging tab, find debug categories
you are interested in (qt.scenegraph.* or qt.quick.* for example), and enable the checkbox in the
Debug column.
\section2 Scene graph render visualziation
The \l{Qt Quick} renderer also has a number of built-in diagnostic visualizations. Those can
be usually only enabled at application startup. This is inconvenient however if you first need
to navigate to the relevant part of your application to investigate a specific issue.
The GammaRay \l{Qt Quick 2 Inspector} allows to enable these diagnostic render modes at runtime
too (only available in some Qt versions). The toolbar above the scene view in the lower left part
of the Qt Quick inspector view has toggle actions for them.
In our example, the batch rendering visualization is particularly interesting. Areas of the same
color indicate batches of elements that are rendered in a single draw call. This is the optimal scenario
we are trying to achieve. Areas with diagonal lines represent sets of items that have some Common
state but are rendered by individual draw calls. The scene graph renderer calls this case "unmerged
batch". In our example one observes a colorful output with all inactive elements in the sliders in
their own colors.
\section2 Scene graph inspection
After having established that our problem comes from rectangles not being batched in the scene graph renderer, we
need to investigate what prevents batching in our case. Items for example can't be batched when they
use clipping or differ in their opacity. For Qt versions < 5.8 batching is also disabled if
non-opaque items overlap, or when Items have a non-trivial transformation matrix.
For this we use the scene graph view of the \l{Qt Quick 2 Inspector} view in GammaRay. It shows the
internal scene graph items, which is what the renderer uses as input for the batching.
Comparing the subtrees belonging to active and inactive rectangles scenegraph-node tree view,
we notice that the inactive ones have an Opacity node, while the active ones don't. The opacity
node indicates transparency.
Now we can check the opacity property in the \l {Properties} tab of the Item view, so we switch back to
"Items". The Item corresponding to the previously selected Opacity node is already pre-selected, so
we only need to look for the property. In fact we find it to have value < 1.
In order to match this to the actual code causing the problem, use the context menu action
"Go to declaration", which will open a code editor around the following piece of code:
\snippet quick-batching/Slider.qml Slider delegate
In fact we see that the opacity value is set to a value depending on the index. That means that all
rectangles get a different opacity value and that rules out batching.
In order to verify that this is actually our problem you don't need to restart the application,
you can also use the editing capabilities of the \l{Properties} tab in the item tree view to adjust
the opacity live. If you still have the batch rendering visualization activated, after setting the
opacity to 1, you'll observe how the selected rectangle gets the same color as all the active
rectangles.
Just removing the opacity is of course not a proper fix, it merely verifies that it's these opacities
causing our performance problem.
To retain the same visual appearance as with opacity set, you could e.g. use the alpha component of
the color property to obtain the transparency, without impairing the batching.
*/
|