Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmlprofileradapter.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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
6
7#include <private/qqmldebugserviceinterfaces_p.h>
8
10
11QQmlProfilerAdapter::QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEnginePrivate *engine)
12{
13 engine->profiler = new QQmlProfiler;
14 init(service, engine->profiler);
15}
16
17QQmlProfilerAdapter::QQmlProfilerAdapter(QQmlProfilerService *service, QQmlTypeLoader *loader)
18{
19 QQmlProfiler *profiler = new QQmlProfiler;
20 loader->setProfiler(profiler);
21 init(service, profiler);
22}
23
24void QQmlProfilerAdapter::init(QQmlProfilerService *service, QQmlProfiler *profiler)
25{
26 next = 0;
27 setService(service);
28 connect(this, &QQmlProfilerAdapter::profilingEnabled,
29 profiler, &QQmlProfiler::startProfiling);
30 connect(this, &QQmlAbstractProfilerAdapter::profilingEnabledWhileWaiting,
31 profiler, &QQmlProfiler::startProfiling, Qt::DirectConnection);
32 connect(this, &QQmlAbstractProfilerAdapter::profilingDisabled,
33 profiler, &QQmlProfiler::stopProfiling);
34 connect(this, &QQmlAbstractProfilerAdapter::profilingDisabledWhileWaiting,
35 profiler, &QQmlProfiler::stopProfiling, Qt::DirectConnection);
36 connect(this, &QQmlAbstractProfilerAdapter::dataRequested,
37 profiler, &QQmlProfiler::reportData);
38 connect(this, &QQmlAbstractProfilerAdapter::referenceTimeKnown,
39 profiler, &QQmlProfiler::setTimer);
40 connect(profiler, &QQmlProfiler::dataReady,
41 this, &QQmlProfilerAdapter::receiveData);
42}
43
44// convert to QByteArrays that can be sent to the debug client
45static void qQmlProfilerDataToByteArrays(const QQmlProfilerData &d,
46 QQmlProfiler::LocationHash &locations,
47 QList<QByteArray> &messages)
48{
49 QQmlDebugPacket ds;
50 Q_ASSERT_X((d.messageType & (1 << 31)) == 0, Q_FUNC_INFO,
51 "You can use at most 31 message types.");
52 for (quint32 decodedMessageType = 0; (d.messageType >> decodedMessageType) != 0;
53 ++decodedMessageType) {
54 if (decodedMessageType == QQmlProfilerDefinitions::RangeData
55 || (d.messageType & (1 << decodedMessageType)) == 0) {
56 continue; // RangeData is sent together with RangeLocation
57 }
58
59 if (decodedMessageType == QQmlProfilerDefinitions::RangeEnd
60 || decodedMessageType == QQmlProfilerDefinitions::RangeStart) {
61 ds << d.time << decodedMessageType << static_cast<quint32>(d.detailType);
62 if (d.locationId != 0)
63 ds << static_cast<qint64>(d.locationId);
64 } else {
65 auto i = locations.constFind(d.locationId);
66 if (i != locations.cend()) {
67 ds << d.time << decodedMessageType << static_cast<quint32>(d.detailType);
68 ds << (i->url.isEmpty() ? i->location.sourceFile : i->url.toString())
69 << static_cast<qint32>(i->location.line)
70 << static_cast<qint32>(i->location.column);
71 if (d.messageType & (1 << QQmlProfilerDefinitions::RangeData)) {
72 // Send both, location and data ...
73 ds << static_cast<qint64>(d.locationId);
74 messages.append(ds.squeezedData());
75 ds.clear();
76 ds << d.time << int(QQmlProfilerDefinitions::RangeData)
77 << static_cast<quint32>(d.detailType)
78 << (i->location.sourceFile.isEmpty() ? i->url.toString() :
79 i->location.sourceFile);
80 }
81 ds << static_cast<qint64>(d.locationId);
82 locations.erase(i); // ... so that we can erase here without missing anything.
83 } else {
84 // Skip RangeData and RangeLocation: We've already sent them
85 continue;
86 }
87 }
88 messages.append(ds.squeezedData());
89 ds.clear();
90 }
91}
92
93qint64 QQmlProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
94{
95 while (next != data.size()) {
96 const QQmlProfilerData &nextData = data.at(next);
97 if (nextData.time > until || messages.size() > s_numMessagesPerBatch)
98 return nextData.time;
99 qQmlProfilerDataToByteArrays(nextData, locations, messages);
100 ++next;
101 }
102
103 next = 0;
104 data.clear();
105 locations.clear();
106 return -1;
107}
108
109void QQmlProfilerAdapter::receiveData(const QVector<QQmlProfilerData> &new_data,
110 const QQmlProfiler::LocationHash &new_locations)
111{
112 if (data.isEmpty())
113 data = new_data;
114 else
115 data.append(new_data);
116
117 if (locations.isEmpty())
118 locations = new_locations;
119 else
120 locations.insert(new_locations);
121
122 service->dataReady(this);
123}
124
125QT_END_NAMESPACE
126
127#include "moc_qqmlprofileradapter.cpp"
static void qQmlProfilerDataToByteArrays(const QQmlProfilerData &d, QQmlProfiler::LocationHash &locations, QList< QByteArray > &messages)