1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qquick3dprofiler_p.h"
5
6#include <QtQml/private/qqmlabstractprofileradapter_p.h>
7#include <QtQml/qqmlfile.h>
8
9#include <QtCore/qcoreapplication.h>
10#include <QtCore/qthread.h>
11
12QT_BEGIN_NAMESPACE
13
14// Enable to debug profiling without client app.
15//#define PROFILE_WITHOUT_CLIENT
16
17// instance will be set, unset in constructor. Allows static methods to be inlined.
18QQuick3DProfiler *QQuick3DProfiler::s_instance = nullptr;
19#ifdef PROFILE_WITHOUT_CLIENT
20quint64 QQuick3DProfiler::featuresEnabled = 0xffffffff;
21#else
22quint64 QQuick3DProfiler::featuresEnabled = 0;
23#endif
24QHash<QByteArray, int> QQuick3DProfiler::s_eventData = {};
25QHash<int, QByteArray> QQuick3DProfiler::s_eventDataRev = {};
26QMutex QQuick3DProfiler::s_eventDataMutex;
27
28QQuick3DProfilerData::QQuick3DProfilerData(qint64 time, int messageType, int detailType, qint64 d1, qint64 d2, const QList<int> &ids)
29 : QQuick3DProfilerData(time, messageType, detailType, d1, d2)
30{
31 static int ID_MARKER = 0xed000000;
32 int size = qMin(a: ids.size(), b: s_numSupportedIds);
33 for (int i = 0; i < size; i++)
34 this->ids[i] = ids[i] | ID_MARKER;
35}
36
37int QQuick3DProfiler::registerObject(const QObject *object)
38{
39 QMutexLocker lock(&s_eventDataMutex);
40
41#ifdef PROFILE_WITHOUT_CLIENT
42 if (!s_instance)
43 s_instance = new QQuick3DProfiler(nullptr);
44#else
45 if (!s_instance)
46 return 0;
47#endif
48 QQmlData *qmlData = QQmlData::get(object);
49 QByteArray typeAndLocation;
50 int id = 0;
51 if (qmlData) {
52 QQmlType qmlType = QQmlMetaType::qmlType(object->metaObject());
53 QString fileName = qmlData->compilationUnit->fileName();
54 typeAndLocation = (qmlType.qmlTypeName() + QLatin1Char(' ') + fileName + QLatin1Char(':') + QString::number(qmlData->lineNumber)).toUtf8();
55 if (!s_eventData.contains(key: typeAndLocation)) {
56 id = s_eventData.size() + 1;
57 s_eventData.insert(key: typeAndLocation, value: id);
58 s_eventDataRev.insert(key: id, value: typeAndLocation);
59 s_instance->processMessage(message: QQuick3DProfilerData(s_instance->timestamp(), Quick3DFrame, Quick3DEventData, id, 0));
60 } else {
61 id = s_eventData.value(key: typeAndLocation);
62 }
63 }
64 return id;
65}
66
67int QQuick3DProfiler::registerString(const QByteArray &string)
68{
69 QMutexLocker lock(&s_eventDataMutex);
70#ifdef PROFILE_WITHOUT_CLIENT
71 if (!s_instance)
72 s_instance = new QQuick3DProfiler(nullptr);
73#else
74 if (!s_instance)
75 return 0;
76#endif
77 int id = 0;
78 if (!s_eventData.contains(key: string)) {
79 id = s_eventData.size() + 1;
80 s_eventData.insert(key: string, value: id);
81 s_eventDataRev.insert(key: id, value: string);
82 s_instance->processMessage(message: QQuick3DProfilerData(s_instance->timestamp(), Quick3DFrame, Quick3DEventData, id, 0));
83 } else {
84 id = s_eventData.value(key: string);
85 }
86 return id;
87}
88
89void QQuick3DProfiler::initialize(QObject *parent)
90{
91 Q_ASSERT(s_instance == nullptr);
92 s_instance = new QQuick3DProfiler(parent);
93}
94
95QQuick3DProfiler::QQuick3DProfiler(QObject *parent)
96 : QObject(parent)
97{
98 m_timer.start();
99}
100
101QQuick3DProfiler::~QQuick3DProfiler()
102{
103 QMutexLocker lock(&m_dataMutex);
104 featuresEnabled = 0;
105 s_instance = nullptr;
106}
107
108void QQuick3DProfiler::startProfilingImpl(quint64 features)
109{
110 QMutexLocker lock(&m_dataMutex);
111 featuresEnabled = features;
112}
113
114void QQuick3DProfiler::stopProfilingImpl()
115{
116 QMutexLocker lock(&m_dataMutex);
117 featuresEnabled = 0;
118 emit dataReady(data: m_data, eventData: s_eventDataRev);
119 m_data.clear();
120}
121
122void QQuick3DProfiler::reportDataImpl()
123{
124 QMutexLocker lock(&m_dataMutex);
125 emit dataReady(data: m_data, eventData: s_eventDataRev);
126 m_data.clear();
127}
128
129void QQuick3DProfiler::setTimer(const QElapsedTimer &t)
130{
131 QMutexLocker lock(&m_dataMutex);
132 m_timer = t;
133}
134
135QT_END_NAMESPACE
136

source code of qtquick3d/src/utils/qquick3dprofiler.cpp