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 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>; |
14 | |
15 | QQuick3DProfilerAdapter::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 | |
36 | QQuick3DProfilerAdapter::~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 |
44 | static 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 | |
74 | qint64 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 | |
87 | void 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 | |
97 | QT_END_NAMESPACE |
98 | |