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