/*
  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.
*/
