aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils/qquick3dprofiler.cpp
blob: 6c9e3448554b9819ccd292e4176cb38616efde4d (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only

#include "qquick3dprofiler_p.h"

#include <QtQml/qqmlfile.h>

#include <QtCore/qcoreapplication.h>
#include <QtCore/qthread.h>

QT_BEGIN_NAMESPACE

#if QT_CONFIG(qml_debug)

// Enable to debug profiling without client app.
//#define PROFILE_WITHOUT_CLIENT

// instance will be set, unset in constructor. Allows static methods to be inlined.
QQuick3DProfiler *QQuick3DProfiler::s_instance = nullptr;
#ifdef PROFILE_WITHOUT_CLIENT
quint64 QQuick3DProfiler::featuresEnabled = 0xffffffff;
#else
quint64 QQuick3DProfiler::featuresEnabled = 0;
#endif
QHash<QByteArray, int> QQuick3DProfiler::s_eventData = {};
QHash<int, QByteArray> QQuick3DProfiler::s_eventDataRev = {};
QMutex QQuick3DProfiler::s_eventDataMutex;

QQuick3DProfilerData::QQuick3DProfilerData(qint64 time, int messageType, int detailType, qint64 d1, qint64 d2, const QList<int> &ids)
    : QQuick3DProfilerData(time, messageType, detailType, d1, d2)
{
    static int ID_MARKER = 0xed000000;
    int size = qMin(ids.size(), s_numSupportedIds);
    for (int i = 0; i < size; i++)
        this->ids[i] = ids[i] | ID_MARKER;
}

int QQuick3DProfiler::registerObject(const QObject *object)
{
    QMutexLocker lock(&s_eventDataMutex);

#ifdef PROFILE_WITHOUT_CLIENT
    if (!s_instance)
        s_instance = new QQuick3DProfiler(nullptr);
#else
    if (!s_instance)
        return 0;
#endif
    QQmlData *qmlData = QQmlData::get(object);
    QByteArray typeAndLocation;
    int id = 0;
    if (qmlData) {
        QQmlType qmlType = QQmlMetaType::qmlType(object->metaObject());
        QString fileName = qmlData->compilationUnit->fileName();
        typeAndLocation = (qmlType.qmlTypeName() + QLatin1Char(' ') + fileName + QLatin1Char(':') + QString::number(qmlData->lineNumber)).toUtf8();
        if (!s_eventData.contains(typeAndLocation)) {
            id = s_eventData.size() + 1;
            s_eventData.insert(typeAndLocation, id);
            s_eventDataRev.insert(id, typeAndLocation);
            s_instance->processMessage(QQuick3DProfilerData(s_instance->timestamp(), Quick3DFrame, Quick3DEventData, id, 0));
        } else {
            id = s_eventData.value(typeAndLocation);
        }
    }
    return id;
}

int QQuick3DProfiler::registerString(const QByteArray &string)
{
    QMutexLocker lock(&s_eventDataMutex);
#ifdef PROFILE_WITHOUT_CLIENT
    if (!s_instance)
        s_instance = new QQuick3DProfiler(nullptr);
#else
    if (!s_instance)
        return 0;
#endif
    int id = 0;
    if (!s_eventData.contains(string)) {
        id = s_eventData.size() + 1;
        s_eventData.insert(string, id);
        s_eventDataRev.insert(id, string);
        s_instance->processMessage(QQuick3DProfilerData(s_instance->timestamp(), Quick3DFrame, Quick3DEventData, id, 0));
    } else {
        id = s_eventData.value(string);
    }
    return id;
}

void QQuick3DProfiler::initialize(QObject *parent)
{
    Q_ASSERT(s_instance == nullptr);
    s_instance = new QQuick3DProfiler(parent);
}

QQuick3DProfiler::QQuick3DProfiler(QObject *parent)
    : QObject(parent)
{
    m_timer.start();
}

QQuick3DProfiler::~QQuick3DProfiler()
{
    QMutexLocker lock(&m_dataMutex);
    featuresEnabled = 0;
    s_instance = nullptr;
}

void QQuick3DProfiler::startProfilingImpl(quint64 features)
{
    QMutexLocker lock(&m_dataMutex);
    featuresEnabled = features;
}

void QQuick3DProfiler::stopProfilingImpl()
{
    QMutexLocker lock(&m_dataMutex);
    featuresEnabled = 0;
    emit dataReady(m_data, s_eventDataRev);
    m_data.clear();
}

void QQuick3DProfiler::reportDataImpl()
{
    QMutexLocker lock(&m_dataMutex);
    emit dataReady(m_data, s_eventDataRev);
    m_data.clear();
}

void QQuick3DProfiler::setTimer(const QElapsedTimer &t)
{
    QMutexLocker lock(&m_dataMutex);
    m_timer = t;
}

#endif
QT_END_NAMESPACE