// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

// **********************************************************************
// NOTE: the sections are not ordered by their logical order to avoid
// reshuffling the file each time the index order changes (i.e., often).
// Run the fixnavi.pl script to adjust the links to the index order.
// **********************************************************************

/*!
    \page creator-how-to-profile-qml.html
    \if defined(qtdesignstudio)
    \previouspage creator-qml-performance-monitor.html
    \nextpage studio-advanced.html
    \else
    \previouspage creator-how-tos.html
    \endif

    \ingroup creator-how-to-analyze

    \title Profile QML applications

    With QML Profiler, you can find causes for typical performance problems
    in your applications, such as slowness and unresponsive, stuttering user
    interfaces.

    \if defined(qtdesignstudio)
    \note In this section, you are using advanced menu items. These are not
    visible by default. To toggle the visibility of advanced menu items, see
    \l{Customizing the Menu Bar}.
    \endif


    To collect data about a QML application:

    \list 1
        \li Set up QML debugging for the project. For more information, see
            \l{Setting Up QML Debugging}.
        \if defined(qtcreator)
        \li In the \uicontrol Projects mode, select a \l{Kits}
            {kit} with Qt version 4.7.4 or later.
       \endif
            \note To profile applications on \l{glossary-device}{devices}, you
            must install Qt libraries on them.
        \li Go to \uicontrol Analyze > \uicontrol {QML Profiler} to profile the
            current application.
            \image qtcreator-qml-profiler-toolbar.webp {QML Profiler}
        \li Select \inlineimage icons/qtcreator-analyze-start-button.png
            (\uicontrol Start) to start the application from QML Profiler.
    \endlist

    QML Profiler immediately begins to collect data, as indicated by
    the time running in the \uicontrol Elapsed field.

    \note If data collection does not start automatically, select
    \inlineimage icons/recordfill.png (\uicontrol {Enable Profiling}).

    Data is collected until you select \inlineimage icons/recordfill.png again.
    Data collection takes time, so expect a delay before seeing data.

    Do not use application commands to exit the application because data is
    sent to QML Profiler when you select \inlineimage icons/recordfill.png.
    The application stops in seconds. If you exit the application, the data is
    not sent.

    Select \uicontrol {Disable Profiling} to disable the automatic start of the
    data collection when an application is launched. Data collection starts when
    you select the button again.

    To save all the collected data, select \uicontrol Analyze >
    \uicontrol {QML Profiler Options} > \uicontrol {Save QML Trace}. To view the saved
    data, select \uicontrol {Load QML Trace}. You can also deliver the saved data to
    others for examination or load data saved by them.

    \section1 Flush data while profiling

    Set data flushing preferences either globally for all projects or separately
    for each project.

    To set global preferences, go to \preferences >
    \uicontrol Analyzer > \uicontrol {QML Profiler}.

    To specify custom QML Profiler settings for a particular project:

    \list 1
        \li Go to \uicontrol Projects > \uicontrol Run.
        \li In \uicontrol {QML Profiler Settings}, select \uicontrol Custom.
            \image qml-profiler-settings.png {QML Profiler Settings}
    \endlist

    You can set the following preferences:

    \table
    \header
        \li Setting
        \li Value
    \row
        \li \uicontrol {Flush data while profiling}
        \li Flush the data periodically instead of flushing all data when
            profiling stops. This saves memory on the target device and shortens
            the wait between the profiling being stopped and the data
            being displayed.
    \row
        \li \uicontrol {Flush interval}
        \li Set the flush interval in
            milliseconds. The shorter the interval, the more often the
            data is flushed. The longer the interval, the more data has
            to be buffered in the target application, potentially wasting
            memory. However, the flushing itself takes time, which can
            distort the profiling results.
    \row
        \li \uicontrol {Process data only when process ends}
        \li Aggregate data from many QML engines into one trace. Otherwise,
            the profiling stops when one of the engines stops.
    \endtable

    To restore the global settings for the project, select
    \uicontrol {Restore Global}.

    \section1 Attach to a running Qt Quick application

    You can profile a Qt Quick application that you do not run from \QC.
    However, you must enable QML debugging and profiling for the application
    in the project build settings. For more information, see
    \l{Setting Up QML Debugging}.

    To attach to a waiting application:

    \list 1
        \li Go to \uicontrol Analyze >
            \uicontrol {QML Profiler (Attach to Waiting Application)}.
            \image qml-profiler-start-dialog.png {Start QML Profiler dialog}
         \li In \uicontrol Kit, select the kit used to build the application.
         \li In \uicontrol Port, specify the port to listen to.
         \li Select \uicontrol OK.
    \endlist

    \sa {Profiling QML applications}

    \if defined(qtcreator)
    \sa {Analyze}{How To: Analyze}, {Analyzers}, {Analyzing Code}
    \endif
*/

/*!
    \page creator-qml-performance-monitor.html
    \if defined(qtdesignstudio)
    \previouspage creator-qml-debugging-example.html
    \nextpage creator-how-to-profile-qml.html
    \else
    \previouspage creator-reference.html
    \endif

    \ingroup creator-reference-analyzer

    \title Profiling QML Applications

    \brief Improve the performance of QML applications.

    \if defined(qtdesignstudio)
    \note In this section, you are using advanced menu items. These are not
    visible by default. To toggle the visibility of advanced menu items, see
    \l{Customizing the Menu Bar}.
    \endif

    With QML Profiler, you can find causes for typical performance problems
    in your applications, such as slowness and unresponsive, stuttering user
    interfaces. Typical causes include executing too much JavaScript in too few
    frames. All JavaScript must return before the GUI thread can proceed, and
    frames are delayed or dropped if the GUI thread is not ready.

    Another typical cause for similar performance problems is creating or
    updating invisible items, which takes time in the GUI thread.

    \if defined(qtcreator)
    Triggering long-running C++ functions, such as paint methods and signal
    handlers, also takes time in the GUI thread, but is more difficult to see in
    QML Profiler because it does not profile C++ code.
    \endif

    To find excessive use of JavaScript, check the frame rate in animations and
    Scene Graph events, look for gaps, and check whether the application behaves
    as expected. The JavaScript category displays the run time of functions,
    which you should try to keep below 16 ms per frame.

    To find problems caused by handling invisible items, look for dropped
    frames and check that you are not using too many short bindings or signal
    handlers that are updated per frame. You can also \l{Visualizing Overdraw}
    {visualize Scene Graph overdraw} to check scene layout and find items that
    are never visible to the users because they are located outside the screen
    or hidden beneath other, visible elements.

    \if defined(qtcreator)
    If frames get dropped even though JavaScript is not being run, and there are
    large, unexplained gaps in the timeline, check your custom QQuickItem
    implementations. You can use \l{Profile function execution}
    {Valgrind Callgrind} or other general purpose profilers to analyze C++ code.

    You can use \e {full stack tracing} to trace from the top level QML or
    JavaScript down to the C++ and all the way to the kernel space. You can
    view the collected data in the \l{Chrome Trace Format Visualizer}
    {Chrome Trace Format Viewer}.
    \endif

    \section1 Analyzing Collected Data

    The \uicontrol Timeline view displays graphical representations of QML and
    JavaScript execution and a condensed view of all recorded events.

    \image qtcreator-qml-profiler.webp {QML Profiler}

    Each row in the timeline (6) describes a type of QML events that were
    recorded. Move the cursor on an event on a row to see how long it takes and
    where in the source it is being called. To display the information only when
    an event is selected, turn off \uicontrol {View Event Information on Mouseover}
    (4).

    The outline (10) summarizes the period for which data was collected. Drag
    the zoom range (8) or click the outline to move on the outline. You can
    also move between events by selecting \uicontrol {Jump to Previous Event}
    and \uicontrol {Jump to Next Event} (1).

    Select \uicontrol {Show Zoom Slider} (2) to open a slider that sets the zoom
    level. You can also drag the zoom handles (9). To reset
    the default zoom level, right-click the timeline to open the context menu,
    and select \uicontrol {Reset Zoom}.

    Click the time ruler to add vertical orientation lines (5) to the timeline.

    \section2 Selecting Event Ranges

    Select an event range (7) to view the frame rate of events and to
    compare it with the frame rate of similar events. Select
    \uicontrol {Select Range} (3) to activate the selection tool. Then click in
    the timeline to specify the beginning of the event range. Drag the selection
    handle to define the end of the range. The length of the range indicates the
    frame rate of the event.

    To measure delays between two subsequent events, place an event range between
    the end of the first event and the beginning of the second event. The
    \uicontrol Duration field displays the delay between the
    events in milliseconds.

    To zoom into an event range, double-click it.

    To narrow down the current range in the \uicontrol Timeline,
    \uicontrol Statistics, and \uicontrol {Flame Graph} views, right-click
    the range and select \uicontrol {Analyze Current Range}. To return to
    the full range, select \uicontrol {Analyze Full Range} in the context menu.

    To remove an event range, close the \uicontrol Selection dialog.

    \section2 Understanding the Data

    Generally, events in the timeline view indicate how long QML or JavaScript
    execution took. Move the mouse over them to see details. For most events,
    they include location in source code, duration and some relevant parts of
    the source code itself.

    Select an event to move the cursor in the code editor to the part
    of the code the event is associated with.

    The following types of events are displayed in the timeline view on one or
    several rows.

    \table

    \header
        \li Event Category
        \li Description
    \row
        \li \uicontrol {Pixmap Cache}
        \li Displays the general amount of pixmap data cached, in pixels. In
            addition, displays a separate event for each picture being loaded,
            with specifics about its file name and size.

    \row
        \li \uicontrol {Scene Graph}
        \li Displays the time when scene graph frames are rendered and some
            additional timing information for the various stages executed to do
            so.
    \row
        \li \uicontrol {Memory Usage}
        \li Displays block allocations of the JavaScript memory manager.
            Generally, the memory manager will reserve larger blocks of memory
            in one piece and later hand them out to the application in smaller
            bits. If the application requests single blocks of memory
            surpassing a certain size, the memory manager will allocate those
            separately. Those two modes of operation are shown as events of
            different colors.
            The second row displays the actual usage of the allocated memory.
            This is the amount of JavaScript heap the application has actually
            requested.
    \row
        \li \uicontrol {Input Events}
        \li Displays mouse and keyboard events.
    \row
        \li \uicontrol Painting
        \li Not used.
    \row
        \li \uicontrol Animations
        \li Displays the amount of animations that are active and the frame
            rate that they are running at.
            Render thread animations are shown on a separate row.
    \row
        \li \uicontrol Compiling
        \li Displays the time spent compiling the QML files.
    \row
        \li \uicontrol Creating
        \li Displays the time spent creating the elements in the scene.
            The creation of elements takes place in two stages. The first
            stage is for the creation of the data structures, including child
            elements. The second stage represents the completion callbacks. Not
            all elements trigger completion callbacks, though. The stages are
            shown as separate events in the timeline.
    \row
        \li \uicontrol Binding
        \li Displays the time when a binding is evaluated and how long the
            evaluation takes.
    \row
        \li \uicontrol {Handling Signal}
        \li Displays the time when a signal is handled and how long the
            handling takes.
    \row
        \li \uicontrol JavaScript
        \li Displays the time spent executing the actual JavaScript behind
            bindings and signal handlers. It lists all the JavaScript functions
            you may be using to evaluate bindings or handle signals.
    \row
        \li \uicontrol Quick3D
        \li Displays the time spent rendering Qt Quick 3D frames, timing information
            for frame preparation and synchronization, particle system update times
            and particle update count, as well as texture and mesh memory allocations
            and memory consumption.

            This event type is available since Qt 6.3.
    \endtable

    \section2 Analyzing Scene Graph Events

    To understand the scene graph category, read more about how
    Qt Quick scene graph works in \l {Qt Quick Scene Graph} and
    \l {Qt Quick Scene Graph Default Renderer}. The following events are reported in the
    \uicontrol {Scene Graph} category. Not all events are generated by all render
    loops. In the Windows and Basic render loops everything runs in the same
    thread and the distinction between GUI thread and render thread is
    meaningless.

    Set the environment variable QSG_RENDER_TIMING, to get a textual
    output of similar, but slightly different timings from the application
    being profiled. The differences are listed below.

    \table
    \header
        \li Event Type
        \li Thread
        \li Render Loop Types
        \li Label in output of QSG_RENDER_TIMING
        \li Description
    \row
        \li \uicontrol {Polish}
        \li GUI
        \li Threaded, Basic, Windows
        \li polish
        \li Final touch-up of items before they are rendered using
            QQuickItem::updatePolish().
    \row
        \li \uicontrol {GUI Thread Wait}
        \li GUI
        \li Threaded
        \li lock
        \li Executing slots connected to the QQuickWindow::afterAnimating()
            signal and then locking the render thread's mutex before waiting on
            the same mutex at \uicontrol {GUI Thread Sync}. If this starts long
            before \uicontrol {Render Thread Sync}, there is \e free  time in the GUI
            thread you could be using for running additional QML or JavaScript.
    \row
        \li \uicontrol {GUI Thread Sync}
        \li GUI
        \li Threaded
        \li blockedForSync
        \li The time the GUI thread is blocked, waiting for the render thread.
    \row
        \li \uicontrol {Animations}
        \li GUI
        \li Threaded, Windows
        \li animations
        \li Advancing animations in the GUI thread. The basic render loop does
            not drive animations in sync with the rendering. This is why no
            animation events will be shown when using the basic render loop.
            Watch the \uicontrol {Animations} category to see animation timing in
            this case.
    \row
        \li \uicontrol {Render Thread Sync}
        \li Render
        \li Threaded, Basic, Windows
        \li Frame rendered ... sync
        \li Synchronizing the QML state into the scene graph using
            QQuickItem::updatePaintNode().
    \row
        \li \uicontrol {Render}
        \li Render
        \li Threaded, Basic, Windows
        \li Frame rendered ... render
        \li Total time spent rendering the frame, including preparing and
            uploading all the necessary data to the GPU. This is the \e gross
            render time. Do not confuse it with the \e net \uicontrol{Render Render}
            time below.
    \row
        \li \uicontrol {Swap}
        \li Render
        \li Threaded, Basic, Windows
        \li Frame rendered ... swap
        \li Swapping frames after rendering.
    \row
        \li \uicontrol {Render Preprocess}
        \li Render
        \li Threaded, Basic, Windows
        \li time in renderer ... preprocess
        \li Calling QSGNode::preprocess() on all nodes that need to be
            preprocessed. This is part of the gross \uicontrol {Render} step.
    \row
        \li \uicontrol {Render Update}
        \li Render
        \li Threaded, Basic, Windows
        \li time in renderer ... updates
        \li Iterating and processing all the nodes in the scene graph to update
            their geometry, transformations, opacity, and other state. In the
            \uicontrol {Render Thread Sync} stage, each node is updated separately
            with state from the GUI thread. In \uicontrol {Render Update}, all the
            nodes are combined to create the final scene. This is part of the
            gross \uicontrol {Render} step.
    \row
        \li \uicontrol {Render Bind}
        \li Render
        \li Threaded, Basic, Windows
        \li time in renderer ... binding
        \li Binding the correct framebuffer for OpenGL rendering. This is part
            of the gross \uicontrol {Render} step.
    \row
        \li \uicontrol {Render Render}
        \li Render
        \li Threaded, Basic, Windows
        \li time in renderer ... rendering
        \li The actual process of sending all the data to the GPU via OpenGL.
            This is part of the gross \uicontrol {Render} step.
    \row
        \li \uicontrol {Material Compile}
        \li Render
        \li Threaded, Basic, Windows
        \li shader compiled
        \li Compiling GLSL shader programs.
    \row
        \li \uicontrol {Glyph Render}
        \li Render
        \li Threaded, Basic, Windows
        \li glyphs ... rendering
        \li Rendering of font glyphs into textures.
    \row
        \li \uicontrol {Glyph Upload}
        \li Render
        \li Threaded, Basic, Windows
        \li glyphs ... upload
        \li Uploading of glyph textures to the GPU.
    \row
        \li \uicontrol {Texture Bind}
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture ... bind
        \li Binding a texture in the OpenGL context using glBindTextures.
    \row
        \li \uicontrol {Texture Convert}
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture ... convert
        \li Converting the format and downscaling an image to make it suitable
            for usage as a texture.
    \row
        \li \uicontrol {Texture Swizzle}
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture ... swizzle
        \li Swizzling the texture data on the CPU if necessary.
    \row
        \li \uicontrol {Texture Upload}
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture ... upload / atlastexture uploaded
        \li Uploading the texture data to the GPU.
    \row
        \li \uicontrol {Texture Mipmap}
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture ... mipmap
        \li Mipmapping a texture on the GPU.
    \row
        \li \uicontrol {Texture Delete}
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture deleted
        \li Deleting a texture from the GPU that became unnecessary.
    \endtable

    \section2 Analyzing Qt Quick 3D Events

    The following is the list of events for Qt Quick 3D. Each rendered frame
    consists of synchronize, prepare, and render phases, which are done in that order.
    Synchronize happens in scene graph synchronizing phase, while prepare and
    render happen in scene graph rendering phase.

    Set the environment variable \c QSG_RENDERER_DEBUG=render to get
    additional textual output of render call counts of different rendering passes.
    These call counts are summed up in the Render Frame event.

    \table
    \header
        \li Event Type
        \li Thread
        \li Description
    \row
        \li \uicontrol {Render Frame}
        \li Render
        \li Render time of a frame. Also shows the number of draw calls.
    \row
        \li \uicontrol {Prepare Frame}
        \li Render
        \li Time taken for preparing a frame. Resources are allocated and loaded
            in the prepare phase. The first frame after scene loading usually takes
            longer than others since most resources are loaded at that time.
    \row
        \li \uicontrol {Synchronize Frame}
        \li Render
        \li Synchronize time of a frame. Synchronize takes care of updating backend
            values from the frontend. Also manages shared resources between Qt Quick
            Scene Graph and Qt Quick 3D.
    \row
        \li \uicontrol {Mesh Load}
        \li Render
        \li Load time of a mesh. Shows total memory usage of all meshes. Also shows
            unloads.
    \row
        \li \uicontrol {Custom Mesh Load}
        \li Render
        \li Load time of a custom mesh. Shows total memory usage of all meshes.
            Also shows unloads.
    \row
        \li \uicontrol {Texture Load}
        \li Render
        \li Load time of a texture. Shows total memory usage of all textures.
            Also shows unloads.
    \row
        \li \uicontrol {Generate Shader}
        \li Render
        \li Time for generating a shader for a material.
    \row
        \li \uicontrol {Load Shader}
        \li Render
        \li Time for loading a built-in shader.
    \row
        \li \uicontrol {Particle Update}
        \li GUI
        \li Update time of a particle system. Shows the number of particles updated.
    \row
        \li \uicontrol {Mesh Memory Consumption}
        \li Render
        \li Shows a bar view of total mesh memory consumption.
    \row
        \li \uicontrol {Texture Memory Consumption}
        \li Render
        \li Shows a bar view of total texture memory consumption.
    \endtable

    \section1 Viewing Statistics

    The \uicontrol Statistics view displays the number of times each binding, create,
    compile, JavaScript, or signal event is triggered and the average time it
    takes. Examine the statistics to learn which events to optimize. A high
    number of occurrences might indicate that an event is triggered
    unnecessarily. To view the median, longest, and shortest time for the
    occurrences, select \uicontrol {Extended Event Statistics} in the context menu.

    Select an event to move to it in the source code
    in the code editor.

    \image qml-profiler-statistics.png "Statistics view"

    \uicontrol Callers and \uicontrol Callees show dependencies between events.
    They allow you to examine the internal functions of the application.
    \uicontrol Callers summarizes the QML events that trigger a binding.
    This tells you what caused a change in a binding.
    \uicontrol Callees summarizes the QML events that a binding triggers.
    This tells you which QML events are affected if you change a binding.

    Select an event to move to it in the source code in the code editor.

    When you select an event in the \uicontrol Timeline view, information about
    it is displayed in the \uicontrol Statistics and \uicontrol {Flame Graph}
    views.

    To copy the contents of one view or row to the clipboard, select
    \uicontrol {Copy Table} or \uicontrol {Copy Row} in the context menu.

    \section2 Visualizing Statistics as Flame Graphs

    The \uicontrol {Flame Graph} view shows a more concise statistical overview
    of QML and JavaScript execution. In the \uicontrol {Total Time} view, the
    horizontal bars show the amount of
    time all invocations of a certain function took together, relative to the
    total runtime of all JavaScript and QML events. The nesting shows which
    functions were called by which other ones.

    \image qml-profiler-flamegraph.png "Flame Graph View"

    To view the total amount of memory allocated by the functions, select
    \uicontrol Memory in the drop-down menu.

    To view the number of memory allocations performed by the functions,
    select \uicontrol Allocations.

    Double-click an item in a view to zoom into it. Double-click an empty
    area in the view to zoom out again.

    Unlike the
    \uicontrol Timeline view, the \uicontrol {Flame Graph} view does not show the
    time spans when no QML or JavaScript is running at all. Thus, it is not
    suitable for analyzing per frame execution times. However, it is very easy
    to see the total impact of the various QML and JavaScript events there.

    \sa {Profile QML applications}

    \if defined(qtcreator)
    \sa {Analyze}{How To: Analyze}, {Analyzers}, {Analyzing Code}
    \endif
*/
