Merge master <-> api_changes
[profile/ivi/qtdeclarative.git] / src / qml / debugger / qqmlprofilerservice_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QQMLPROFILERSERVICE_P_H
43 #define QQMLPROFILERSERVICE_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include <private/qqmldebugservice_p.h>
57 #include <QtQml/qtqmlglobal.h>
58 #include <QtCore/qelapsedtimer.h>
59 #include <QtCore/qmutex.h>
60 #include <QtCore/qvector.h>
61 #include <QtCore/qstringbuilder.h>
62
63 QT_BEGIN_HEADER
64
65 QT_BEGIN_NAMESPACE
66
67 struct Q_AUTOTEST_EXPORT QQmlProfilerData
68 {
69     qint64 time;
70     int messageType;
71     int detailType;
72
73     //###
74     QString detailData; //used by RangeData and RangeLocation
75     int line;           //used by RangeLocation
76     int column;         //used by RangeLocation
77     int framerate;      //used by animation events
78     int animationcount; //used by animation events
79
80     QByteArray toByteArray() const;
81 };
82
83 Q_DECLARE_TYPEINFO(QQmlProfilerData, Q_MOVABLE_TYPE);
84
85 class QUrl;
86 class QQmlEngine;
87
88
89 class Q_QML_EXPORT QQmlProfilerService : public QQmlDebugService
90 {
91 public:
92     enum Message {
93         Event,
94         RangeStart,
95         RangeData,
96         RangeLocation,
97         RangeEnd,
98         Complete, // end of transmission
99
100         MaximumMessage
101     };
102
103     enum EventType {
104         FramePaint,
105         Mouse,
106         Key,
107         AnimationFrame,
108         EndTrace,
109         StartTrace,
110
111         MaximumEventType
112     };
113
114     enum RangeType {
115         Painting,
116         Compiling,
117         Creating,
118         Binding,            //running a binding
119         HandlingSignal,     //running a signal handler
120
121         MaximumRangeType
122     };
123
124     static void initialize();
125
126     static bool startProfiling();
127     static bool stopProfiling();
128     static void sendStartedProfilingMessage();
129     static void addEvent(EventType);
130     static void animationFrame(qint64);
131
132     static void sendProfilingData();
133
134     QQmlProfilerService();
135     ~QQmlProfilerService();
136
137 protected:
138     virtual void stateAboutToBeChanged(State state);
139     virtual void messageReceived(const QByteArray &);
140
141 private:
142     bool startProfilingImpl();
143     bool stopProfilingImpl();
144     void sendStartedProfilingMessageImpl();
145     void addEventImpl(EventType);
146     void animationFrameImpl(qint64);
147
148     void startRange(RangeType);
149     void rangeData(RangeType, const QString &);
150     void rangeData(RangeType, const QUrl &);
151     void rangeLocation(RangeType, const QString &, int, int);
152     void rangeLocation(RangeType, const QUrl &, int, int);
153     void endRange(RangeType);
154
155
156     bool profilingEnabled();
157     void setProfilingEnabled(bool enable);
158     void sendMessages();
159     void processMessage(const QQmlProfilerData &);
160
161 private:
162     QElapsedTimer m_timer;
163     bool m_enabled;
164     bool m_messageReceived;
165     QVector<QQmlProfilerData> m_data;
166     QMutex m_mutex;
167
168     static QQmlProfilerService *instance;
169
170     friend struct QQmlBindingProfiler;
171     friend struct QQmlHandlingSignalProfiler;
172     friend struct QQmlObjectCreatingProfiler;
173     friend struct QQmlCompilingProfiler;
174 };
175
176 //
177 // RAII helper structs
178 //
179
180 struct QQmlBindingProfiler {
181     QQmlBindingProfiler(const QString &url, int line, int column)
182     {
183         QQmlProfilerService *instance = QQmlProfilerService::instance;
184         enabled = instance ? instance->profilingEnabled() : false;
185         if (enabled) {
186             instance->startRange(QQmlProfilerService::Binding);
187             instance->rangeLocation(QQmlProfilerService::Binding, url, line, column);
188         }
189     }
190
191     ~QQmlBindingProfiler()
192     {
193         if (enabled)
194             QQmlProfilerService::instance->endRange(QQmlProfilerService::Binding);
195     }
196
197     void addDetail(const QString &details)
198     {
199         if (enabled)
200             QQmlProfilerService::instance->rangeData(QQmlProfilerService::Binding,
201                                                              details);
202     }
203 \
204     bool enabled;
205 };
206
207 struct QQmlHandlingSignalProfiler {
208     QQmlHandlingSignalProfiler()
209     {
210         enabled = QQmlProfilerService::instance
211                 ? QQmlProfilerService::instance->profilingEnabled() : false;
212         if (enabled) {
213             QQmlProfilerService::instance->startRange(
214                         QQmlProfilerService::HandlingSignal);
215         }
216     }
217
218     void setSignalInfo(const QString &name, const QString &expression)
219     {
220         if (enabled)
221             QQmlProfilerService::instance->rangeData(
222                         QQmlProfilerService::HandlingSignal,
223                         name % QLatin1String(": ") % expression);
224     }
225
226     void setLocation(const QString &file, int line, int column)
227     {
228         if (enabled)
229             QQmlProfilerService::instance->rangeLocation(
230                         QQmlProfilerService::HandlingSignal, file, line, column);
231     }
232
233     ~QQmlHandlingSignalProfiler()
234     {
235         if (enabled)
236             QQmlProfilerService::instance->endRange(
237                         QQmlProfilerService::HandlingSignal);
238     }
239
240     bool enabled;
241 };
242
243 struct QQmlObjectCreatingProfiler {
244     QQmlObjectCreatingProfiler()
245     {
246         QQmlProfilerService *instance = QQmlProfilerService::instance;
247         enabled = instance ?
248                     instance->profilingEnabled() : false;
249         if (enabled)
250             instance->startRange(QQmlProfilerService::Creating);
251     }
252
253     void setTypeName(const QString &typeName)
254     {
255         if (enabled)
256             QQmlProfilerService::instance->rangeData(
257                         QQmlProfilerService::Creating, typeName);
258     }
259
260     void setLocation(const QUrl &url, int line, int column)
261     {
262         if (enabled)
263             QQmlProfilerService::instance->rangeLocation(
264                         QQmlProfilerService::Creating, url, line, column);
265     }
266
267     ~QQmlObjectCreatingProfiler()
268     {
269         if (enabled)
270             QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
271     }
272
273     bool enabled;
274 };
275
276 struct QQmlCompilingProfiler {
277     QQmlCompilingProfiler(const QString &name)
278     {
279         QQmlProfilerService *instance = QQmlProfilerService::instance;
280         enabled = instance ?
281                     instance->profilingEnabled() : false;
282         if (enabled) {
283             instance->startRange(QQmlProfilerService::Compiling);
284             instance->rangeLocation(QQmlProfilerService::Compiling, name, 1, 1);
285             instance->rangeData(QQmlProfilerService::Compiling, name);
286         }
287     }
288
289     ~QQmlCompilingProfiler()
290     {
291         if (enabled)
292             QQmlProfilerService::instance->endRange(QQmlProfilerService::Compiling);
293     }
294
295     bool enabled;
296 };
297
298 QT_END_NAMESPACE
299
300 QT_END_HEADER
301
302 #endif // QQMLPROFILERSERVICE_P_H
303