1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2017 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtQml module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qqmlprofilertypedevent_p.h" |
41 | #include "qqmlprofilerclientdefinitions_p.h" |
42 | |
43 | #include <QtCore/qvarlengtharray.h> |
44 | |
45 | QT_BEGIN_NAMESPACE |
46 | |
47 | QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event) |
48 | { |
49 | qint64 time; |
50 | qint32 messageType; |
51 | qint32 subtype; |
52 | |
53 | stream >> time >> messageType; |
54 | |
55 | if (messageType < 0 || messageType > MaximumMessage) |
56 | messageType = MaximumMessage; |
57 | |
58 | RangeType rangeType = MaximumRangeType; |
59 | if (!stream.atEnd()) { |
60 | stream >> subtype; |
61 | if (subtype >= 0 && subtype < MaximumRangeType) |
62 | rangeType = static_cast<RangeType>(subtype); |
63 | } else { |
64 | subtype = -1; |
65 | } |
66 | |
67 | event.event.setTimestamp(time > 0 ? time : 0); |
68 | event.event.setTypeIndex(-1); |
69 | event.serverTypeId = 0; |
70 | |
71 | switch (messageType) { |
72 | case Event: { |
73 | event.type = QQmlProfilerEventType( |
74 | static_cast<Message>(messageType), |
75 | MaximumRangeType, subtype); |
76 | switch (subtype) { |
77 | case StartTrace: |
78 | case EndTrace: { |
79 | QVarLengthArray<qint32> engineIds; |
80 | while (!stream.atEnd()) { |
81 | qint32 id; |
82 | stream >> id; |
83 | engineIds << id; |
84 | } |
85 | event.event.setNumbers<QVarLengthArray<qint32>, qint32>(engineIds); |
86 | break; |
87 | } |
88 | case AnimationFrame: { |
89 | qint32 frameRate, animationCount; |
90 | qint32 threadId; |
91 | stream >> frameRate >> animationCount; |
92 | if (!stream.atEnd()) |
93 | stream >> threadId; |
94 | else |
95 | threadId = 0; |
96 | |
97 | event.event.setNumbers<qint32>({frameRate, animationCount, threadId}); |
98 | break; |
99 | } |
100 | case Mouse: |
101 | case Key: |
102 | int inputType = (subtype == Key ? InputKeyUnknown : InputMouseUnknown); |
103 | if (!stream.atEnd()) |
104 | stream >> inputType; |
105 | qint32 a = -1; |
106 | if (!stream.atEnd()) |
107 | stream >> a; |
108 | qint32 b = -1; |
109 | if (!stream.atEnd()) |
110 | stream >> b; |
111 | |
112 | event.event.setNumbers<qint32>({inputType, a, b}); |
113 | break; |
114 | } |
115 | |
116 | break; |
117 | } |
118 | case Complete: { |
119 | event.type = QQmlProfilerEventType( |
120 | static_cast<Message>(messageType), |
121 | MaximumRangeType, subtype); |
122 | break; |
123 | } |
124 | case SceneGraphFrame: { |
125 | QVarLengthArray<qint64> params; |
126 | qint64 param; |
127 | |
128 | while (!stream.atEnd()) { |
129 | stream >> param; |
130 | params.push_back(t: param); |
131 | } |
132 | |
133 | event.type = QQmlProfilerEventType( |
134 | static_cast<Message>(messageType), |
135 | MaximumRangeType, subtype); |
136 | event.event.setNumbers<QVarLengthArray<qint64>, qint64>(params); |
137 | break; |
138 | } |
139 | case PixmapCacheEvent: { |
140 | qint32 width = 0, height = 0, refcount = 0; |
141 | QString filename; |
142 | stream >> filename; |
143 | if (subtype == PixmapReferenceCountChanged || subtype == PixmapCacheCountChanged) { |
144 | stream >> refcount; |
145 | } else if (subtype == PixmapSizeKnown) { |
146 | stream >> width >> height; |
147 | refcount = 1; |
148 | } |
149 | |
150 | event.type = QQmlProfilerEventType( |
151 | static_cast<Message>(messageType), |
152 | MaximumRangeType, subtype, |
153 | QQmlProfilerEventLocation(filename, 0, 0)); |
154 | event.event.setNumbers<qint32>({width, height, refcount}); |
155 | break; |
156 | } |
157 | case MemoryAllocation: { |
158 | qint64 delta; |
159 | stream >> delta; |
160 | |
161 | event.type = QQmlProfilerEventType( |
162 | static_cast<Message>(messageType), |
163 | MaximumRangeType, subtype); |
164 | event.event.setNumbers<qint64>({delta}); |
165 | break; |
166 | } |
167 | case RangeStart: { |
168 | if (!stream.atEnd()) { |
169 | qint64 typeId; |
170 | stream >> typeId; |
171 | if (stream.status() == QDataStream::Ok) |
172 | event.serverTypeId = typeId; |
173 | // otherwise it's the old binding type of 4 bytes |
174 | } |
175 | |
176 | event.type = QQmlProfilerEventType(MaximumMessage, rangeType, -1); |
177 | event.event.setRangeStage(RangeStart); |
178 | break; |
179 | } |
180 | case RangeData: { |
181 | QString data; |
182 | stream >> data; |
183 | |
184 | event.type = QQmlProfilerEventType(MaximumMessage, rangeType, -1, |
185 | QQmlProfilerEventLocation(), data); |
186 | event.event.setRangeStage(RangeData); |
187 | if (!stream.atEnd()) |
188 | stream >> event.serverTypeId; |
189 | break; |
190 | } |
191 | case RangeLocation: { |
192 | QString filename; |
193 | qint32 line = 0; |
194 | qint32 column = 0; |
195 | stream >> filename >> line; |
196 | |
197 | if (!stream.atEnd()) { |
198 | stream >> column; |
199 | if (!stream.atEnd()) |
200 | stream >> event.serverTypeId; |
201 | } |
202 | |
203 | event.type = QQmlProfilerEventType(MaximumMessage, rangeType, -1, |
204 | QQmlProfilerEventLocation(filename, line, column)); |
205 | event.event.setRangeStage(RangeLocation); |
206 | break; |
207 | } |
208 | case RangeEnd: { |
209 | event.type = QQmlProfilerEventType(MaximumMessage, rangeType, -1); |
210 | event.event.setRangeStage(RangeEnd); |
211 | break; |
212 | } |
213 | default: |
214 | event.event.setNumbers<char>({}); |
215 | event.type = QQmlProfilerEventType( |
216 | static_cast<Message>(messageType), |
217 | MaximumRangeType, subtype); |
218 | break; |
219 | } |
220 | |
221 | return stream; |
222 | } |
223 | |
224 | QT_END_NAMESPACE |
225 | |