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 "qquick3dprofileradapter.h"
5
6#include <QCoreApplication>
7#include <private/qqmldebugconnector_p.h>
8#include <private/qversionedpacket_p.h>
9#include <private/qqmldebugserviceinterfaces_p.h>
10
11QT_BEGIN_NAMESPACE
12
13using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
14
15QQuick3DProfilerAdapter::QQuick3DProfilerAdapter(QObject *parent) :
16 QQmlAbstractProfilerAdapter(parent), next(0)
17{
18 QQuick3DProfiler::initialize(parent: this);
19 // We can always do DirectConnection here as all methods are protected by mutexes
20 connect(sender: this, signal: &QQmlAbstractProfilerAdapter::profilingEnabled,
21 context: QQuick3DProfiler::s_instance, slot: &QQuick3DProfiler::startProfilingImpl, type: Qt::DirectConnection);
22 connect(sender: this, signal: &QQmlAbstractProfilerAdapter::profilingEnabledWhileWaiting,
23 context: QQuick3DProfiler::s_instance, slot: &QQuick3DProfiler::startProfilingImpl, type: Qt::DirectConnection);
24 connect(sender: this, signal: &QQmlAbstractProfilerAdapter::referenceTimeKnown,
25 context: QQuick3DProfiler::s_instance, slot: &QQuick3DProfiler::setTimer, type: Qt::DirectConnection);
26 connect(sender: this, signal: &QQmlAbstractProfilerAdapter::profilingDisabled,
27 context: QQuick3DProfiler::s_instance, slot: &QQuick3DProfiler::stopProfilingImpl, type: Qt::DirectConnection);
28 connect(sender: this, signal: &QQmlAbstractProfilerAdapter::profilingDisabledWhileWaiting,
29 context: QQuick3DProfiler::s_instance, slot: &QQuick3DProfiler::stopProfilingImpl, type: Qt::DirectConnection);
30 connect(sender: this, signal: &QQmlAbstractProfilerAdapter::dataRequested,
31 context: QQuick3DProfiler::s_instance, slot: &QQuick3DProfiler::reportDataImpl, type: Qt::DirectConnection);
32 connect(sender: QQuick3DProfiler::s_instance, signal: &QQuick3DProfiler::dataReady,
33 context: this, slot: &QQuick3DProfilerAdapter::receiveData, type: Qt::DirectConnection);
34}
35
36QQuick3DProfilerAdapter::~QQuick3DProfilerAdapter()
37{
38 if (service)
39 service->removeGlobalProfiler(profiler: this);
40}
41
42
43// convert to QByteArrays that can be sent to the debug client
44static void QQuick3DProfilerDataToByteArrays(const QQuick3DProfilerData &data,
45 QList<QByteArray> &messages,
46 const QHash<int, QByteArray> &eventData)
47{
48 QQmlDebugPacket ds;
49
50 // packet header
51 ds << data.time << data.messageType << data.detailType;
52 // packet data
53 switch (data.messageType) {
54 case QQuick3DProfiler::Event:
55 break;
56 case QQuick3DProfiler::Quick3DFrame:
57 if (data.detailType == QQuick3DProfiler::Quick3DEventData) {
58 ds << eventData[data.subdata1];
59 } else {
60 ds << data.subdata1 << data.subdata2;
61 if (data.ids[0] || data.ids[1])
62 ds << data.ids[0] << data.ids[1];
63 }
64 break;
65 default:
66 Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type.");
67 break;
68 }
69
70 messages.append(t: ds.squeezedData());
71 ds.clear();
72}
73
74qint64 QQuick3DProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
75{
76 while (next < m_data.size()) {
77 if (m_data[next].time <= until && messages.size() <= s_numMessagesPerBatch)
78 QQuick3DProfilerDataToByteArrays(data: m_data[next++], messages, eventData: m_eventData);
79 else
80 return m_data[next].time;
81 }
82 m_data.clear();
83 next = 0;
84 return -1;
85}
86
87void QQuick3DProfilerAdapter::receiveData(const QVector<QQuick3DProfilerData> &new_data, const QHash<int, QByteArray> &eventData)
88{
89 if (m_data.isEmpty())
90 m_data = new_data;
91 else
92 m_data.append(l: new_data);
93 m_eventData = eventData;
94 service->dataReady(profiler: this);
95}
96
97QT_END_NAMESPACE
98

source code of qtquick3d/src/plugins/qmldbg_quick3dprofiler/qquick3dprofileradapter.cpp