aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/util
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@digia.com>2014-01-24 13:24:19 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-15 22:37:38 +0100
commit9424383e6d0ea1dd02dcf1070259e21550da692a (patch)
treef7a9b1372a0a97f997d6a237e3a89e009b07b30e /src/quick/util
parentab6b6b7c7ab544d347d59b7eefad403837d94012 (diff)
Move QtQuick profiling to own profiler adapter
The QtQuick parts of the QML profiler service thus become a proper global profiler which can be independently enabled and disabled. Change-Id: Ifad03801cab2be66a264fc46fdebdae582fcc99b Reviewed-by: Kai Koehne <kai.koehne@digia.com>
Diffstat (limited to 'src/quick/util')
-rw-r--r--src/quick/util/qquickpixmapcache.cpp22
-rw-r--r--src/quick/util/qquickprofiler.cpp205
-rw-r--r--src/quick/util/qquickprofiler_p.h227
-rw-r--r--src/quick/util/util.pri6
4 files changed, 447 insertions, 13 deletions
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 3bff2bb890..a7f9174219 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -71,7 +71,7 @@
#include <QQmlFile>
#include <QMetaMethod>
-#include <private/qqmlprofilerservice_p.h>
+#include <private/qquickprofiler_p.h>
#define IMAGEREQUEST_MAX_REQUEST_COUNT 8
#define IMAGEREQUEST_MAX_REDIRECT_RECURSION 16
@@ -519,7 +519,7 @@ void QQuickPixmapReader::processJobs()
runningJob->loading = true;
QUrl url = runningJob->url;
- Q_QML_PROFILE(pixmapStateChanged<QQmlProfilerService::PixmapLoadingStarted>(url));
+ Q_QUICK_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
QSize requestSize = runningJob->requestSize;
locker.unlock();
@@ -897,10 +897,10 @@ bool QQuickPixmapReply::event(QEvent *event)
if (data->pixmapStatus == QQuickPixmap::Ready) {
data->textureFactory = de->textureFactory;
data->implicitSize = de->implicitSize;
- Q_QML_PROFILE(pixmapLoadingFinished(data->url,
+ Q_QUICK_PROFILE(pixmapLoadingFinished(data->url,
data->requestSize.width() > 0 ? data->requestSize : data->implicitSize));
} else {
- Q_QML_PROFILE(pixmapStateChanged<QQmlProfilerService::PixmapLoadingError>(data->url));
+ Q_QUICK_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(data->url));
data->errorString = de->errorString;
data->removeFromCache(); // We don't continue to cache error'd pixmaps
}
@@ -926,7 +926,7 @@ int QQuickPixmapData::cost() const
void QQuickPixmapData::addref()
{
++refCount;
- Q_QML_PROFILE(pixmapCountChanged<QQmlProfilerService::PixmapReferenceCountChanged>(url, refCount));
+ Q_QUICK_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapReferenceCountChanged>(url, refCount));
if (prevUnreferencedPtr)
pixmapStore()->referencePixmap(this);
}
@@ -935,7 +935,7 @@ void QQuickPixmapData::release()
{
Q_ASSERT(refCount > 0);
--refCount;
- Q_QML_PROFILE(pixmapCountChanged<QQmlProfilerService::PixmapReferenceCountChanged>(url, refCount));
+ Q_QUICK_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapReferenceCountChanged>(url, refCount));
if (refCount == 0) {
if (reply) {
QQuickPixmapReply *cancelReply = reply;
@@ -966,7 +966,7 @@ void QQuickPixmapData::addToCache()
QQuickPixmapKey key = { &url, &requestSize };
pixmapStore()->m_cache.insert(key, this);
inCache = true;
- Q_QML_PROFILE(pixmapCountChanged<QQmlProfilerService::PixmapCacheCountChanged>(
+ Q_QUICK_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
url, pixmapStore()->m_cache.count()));
}
}
@@ -975,7 +975,7 @@ void QQuickPixmapData::removeFromCache()
{
if (inCache) {
QQuickPixmapKey key = { &url, &requestSize };
- Q_QML_PROFILE(pixmapCountChanged<QQmlProfilerService::PixmapCacheCountChanged>(
+ Q_QUICK_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
url, pixmapStore()->m_cache.count()));
pixmapStore()->m_cache.remove(key);
inCache = false;
@@ -1239,17 +1239,17 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
if (!(options & QQuickPixmap::Asynchronous)) {
bool ok = false;
- Q_QML_PROFILE(pixmapStateChanged<QQmlProfilerService::PixmapLoadingStarted>(url));
+ Q_QUICK_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
d = createPixmapDataSync(this, engine, url, requestSize, &ok);
if (ok) {
- Q_QML_PROFILE(pixmapLoadingFinished(url,
+ Q_QUICK_PROFILE(pixmapLoadingFinished(url,
d->requestSize.width() > 0 ? d->requestSize : d->implicitSize));
if (options & QQuickPixmap::Cache)
d->addToCache();
return;
}
if (d) { // loadable, but encountered error while loading
- Q_QML_PROFILE(pixmapStateChanged<QQmlProfilerService::PixmapLoadingError>(url));
+ Q_QUICK_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(url));
return;
}
}
diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp
new file mode 100644
index 0000000000..a706fb1e77
--- /dev/null
+++ b/src/quick/util/qquickprofiler.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickprofiler_p.h"
+#include <private/qqmldebugservice_p.h>
+#include <private/qqmlprofilerservice_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// instance will be set, unset in constructor. Allows static methods to be inlined.
+QQuickProfiler *QQuickProfiler::s_instance = 0;
+bool QQuickProfiler::enabled = false;
+
+// convert to QByteArrays that can be sent to the debug client
+// use of QDataStream can skew results
+// (see tst_qqmldebugtrace::trace() benchmark)
+void QQuickProfilerData::toByteArrays(QList<QByteArray> &messages) const
+{
+ QByteArray data;
+ Q_ASSERT_X(((messageType | detailType) & (1 << 31)) == 0, Q_FUNC_INFO, "You can use at most 31 message types and 31 detail types.");
+ for (uint decodedMessageType = 0; (messageType >> decodedMessageType) != 0; ++decodedMessageType) {
+ if ((messageType & (1 << decodedMessageType)) == 0)
+ continue;
+
+ for (uint decodedDetailType = 0; (detailType >> decodedDetailType) != 0; ++decodedDetailType) {
+ if ((detailType & (1 << decodedDetailType)) == 0)
+ continue;
+
+ //### using QDataStream is relatively expensive
+ QQmlDebugStream ds(&data, QIODevice::WriteOnly);
+ ds << time << decodedMessageType << decodedDetailType;
+
+ switch (decodedMessageType) {
+ case QQuickProfiler::Event:
+ if (decodedDetailType == (int)QQuickProfiler::AnimationFrame)
+ ds << framerate << count;
+ break;
+ case QQuickProfiler::PixmapCacheEvent:
+ ds << detailUrl.toString();
+ switch (decodedDetailType) {
+ case QQuickProfiler::PixmapSizeKnown: ds << x << y; break;
+ case QQuickProfiler::PixmapReferenceCountChanged: ds << count; break;
+ case QQuickProfiler::PixmapCacheCountChanged: ds << count; break;
+ default: break;
+ }
+ break;
+ case QQuickProfiler::SceneGraphFrame:
+ switch (decodedDetailType) {
+ // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime
+ case QQuickProfiler::SceneGraphRendererFrame: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break;
+ // AdaptationLayerFrame: glyphCount (which is an integer), glyphRenderTime, glyphStoreTime
+ case QQuickProfiler::SceneGraphAdaptationLayerFrame: ds << (int)subtime_1 << subtime_2 << subtime_3; break;
+ // ContextFrame: compiling material time
+ case QQuickProfiler::SceneGraphContextFrame: ds << subtime_1; break;
+ // RenderLoop: syncTime, renderTime, swapTime
+ case QQuickProfiler::SceneGraphRenderLoopFrame: ds << subtime_1 << subtime_2 << subtime_3; break;
+ // TexturePrepare: bind, convert, swizzle, upload, mipmap
+ case QQuickProfiler::SceneGraphTexturePrepare: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4 << subtime_5; break;
+ // TextureDeletion: deletionTime
+ case QQuickProfiler::SceneGraphTextureDeletion: ds << subtime_1; break;
+ // PolishAndSync: polishTime, waitTime, syncTime, animationsTime,
+ case QQuickProfiler::SceneGraphPolishAndSync: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break;
+ // WindowsRenderLoop: GL time, make current time, SceneGraph time
+ case QQuickProfiler::SceneGraphWindowsRenderShow: ds << subtime_1 << subtime_2 << subtime_3; break;
+ // WindowsAnimations: update time
+ case QQuickProfiler::SceneGraphWindowsAnimations: ds << subtime_1; break;
+ // WindowsRenderWindow: polish time; always comes packed after a RenderLoop
+ case QQuickProfiler::SceneGraphWindowsPolishFrame: ds << subtime_4; break;
+ default:break;
+ }
+ break;
+ default:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type.");
+ break;
+ }
+ messages << data;
+ data.clear();
+ }
+ }
+}
+
+qint64 QQuickProfiler::sendMessages(qint64 until, QList<QByteArray> &messages)
+{
+ QMutexLocker lock(&m_dataMutex);
+ while (next < m_data.size() && m_data[next].time <= until) {
+ m_data[next++].toByteArrays(messages);
+ }
+ return next < m_data.size() ? m_data[next].time : -1;
+}
+
+void QQuickProfiler::initialize()
+{
+ Q_ASSERT(s_instance == 0);
+ QQmlProfilerService *service = QQmlProfilerService::instance();
+ s_instance = new QQuickProfiler(service);
+ QQmlProfilerService::instance()->addGlobalProfiler(s_instance);
+}
+
+void animationTimerCallback(qint64 delta)
+{
+ Q_QUICK_PROFILE(animationFrame(delta));
+}
+
+QQuickProfiler::QQuickProfiler(QQmlProfilerService *service) :
+ QQmlAbstractProfilerAdapter(service), next(0)
+{
+ // This is safe because at this point the m_instance isn't initialized, yet.
+ m_timer.start();
+
+ // We can always do DirectConnection here as all methods are protected by mutexes
+ connect(this, SIGNAL(profilingEnabled()), this, SLOT(startProfilingImpl()),
+ Qt::DirectConnection);
+ connect(this, SIGNAL(profilingEnabledWhileWaiting()), this, SLOT(startProfilingImpl()),
+ Qt::DirectConnection);
+ connect(this, SIGNAL(referenceTimeKnown(QElapsedTimer)), this, SLOT(setTimer(QElapsedTimer)),
+ Qt::DirectConnection);
+ connect(this, SIGNAL(profilingDisabled()), this, SLOT(stopProfilingImpl()),
+ Qt::DirectConnection);
+ connect(this, SIGNAL(profilingDisabledWhileWaiting()), this, SLOT(stopProfilingImpl()),
+ Qt::DirectConnection);
+ connect(this, SIGNAL(dataRequested()), this, SLOT(reportDataImpl()),
+ Qt::DirectConnection);
+
+ QUnifiedTimer::instance()->registerProfilerCallback(&animationTimerCallback);
+}
+
+QQuickProfiler::~QQuickProfiler()
+{
+ QMutexLocker lock(&m_dataMutex);
+ enabled = false;
+ s_instance = 0;
+}
+
+void QQuickProfiler::startProfilingImpl()
+{
+ QMutexLocker lock(&m_dataMutex);
+ next = 0;
+ m_data.clear();
+ enabled = true;
+}
+
+void QQuickProfiler::stopProfilingImpl()
+{
+ {
+ QMutexLocker lock(&m_dataMutex);
+ enabled = false;
+ next = 0;
+ }
+ service->dataReady(this);
+}
+
+void QQuickProfiler::reportDataImpl()
+{
+ {
+ QMutexLocker lock(&m_dataMutex);
+ next = 0;
+ }
+ service->dataReady(this);
+}
+
+void QQuickProfiler::setTimer(const QElapsedTimer &t)
+{
+ QMutexLocker lock(&m_dataMutex);
+ m_timer = t;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/util/qquickprofiler_p.h b/src/quick/util/qquickprofiler_p.h
new file mode 100644
index 0000000000..d5ad0e9285
--- /dev/null
+++ b/src/quick/util/qquickprofiler_p.h
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPROFILER_P_H
+#define QQUICKPROFILER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qqmlabstractprofileradapter_p.h"
+#include <private/qabstractanimation_p.h>
+#include <QUrl>
+#include <QSize>
+#include <QMutex>
+
+QT_BEGIN_NAMESPACE
+
+#define Q_QUICK_PROFILE_IF_ENABLED(Code)\
+ if (QQuickProfiler::enabled) {\
+ Code;\
+ } else\
+ (void)0
+
+#define Q_QUICK_PROFILE(Method)\
+ Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::Method)
+
+#define Q_QUICK_SG_PROFILE2(Type1, Type2, Params)\
+ Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::sceneGraphFrame<Type1, Type2> Params))
+
+#define Q_QUICK_SG_PROFILE1(Type, Params) Q_QUICK_SG_PROFILE2(Type, Type, Params)
+
+
+// This struct is somewhat dangerous to use:
+// You can save values either with 32 or 64 bit precision. toByteArrays will
+// guess the precision from messageType. If you state the wrong messageType
+// you will get undefined results.
+// The messageType is itself a bit field. You can pack multiple messages into
+// one object, e.g. RangeStart and RangeLocation. Each one will be read
+// independently by toByteArrays. Thus you can only pack messages if their data
+// doesn't overlap. Again, it's up to you to figure that out.
+struct Q_AUTOTEST_EXPORT QQuickProfilerData
+{
+ QQuickProfilerData() {}
+
+ QQuickProfilerData(qint64 time, int messageType, int detailType, const QUrl &url, int x = 0,
+ int y = 0, int framerate = 0, int count = 0) :
+ time(time), messageType(messageType), detailType(detailType), detailUrl(url), x(x), y(y),
+ framerate(framerate), count(count) {}
+
+ QQuickProfilerData(qint64 time, int messageType, int detailType, int framerate = 0,
+ int count = 0) :
+ time(time), messageType(messageType), detailType(detailType), framerate(framerate),
+ count(count) {}
+
+ // Special ctor for scenegraph frames. Note that it's missing the QString/QUrl params.
+ // This is slightly ugly, but makes it easier to disambiguate between int and qint64 params.
+ QQuickProfilerData(qint64 time, int messageType, int detailType, qint64 d1, qint64 d2,
+ qint64 d3, qint64 d4, qint64 d5) :
+ time(time), messageType(messageType), detailType(detailType), subtime_1(d1), subtime_2(d2),
+ subtime_3(d3), subtime_4(d4), subtime_5(d5) {}
+
+
+ qint64 time;
+ int messageType; //bit field of Message
+ int detailType;
+
+ QUrl detailUrl;
+
+ union {
+ qint64 subtime_1;
+ int x; //used for pixmaps
+ };
+
+ union {
+ qint64 subtime_2;
+ int y; //used for pixmaps
+ };
+
+ union {
+ qint64 subtime_3;
+ int framerate; //used by animation events
+ };
+
+ union {
+ qint64 subtime_4;
+ int count; //used by animation events and for pixmaps
+ };
+
+ qint64 subtime_5;
+
+ void toByteArrays(QList<QByteArray> &messages) const;
+};
+
+Q_DECLARE_TYPEINFO(QQuickProfilerData, Q_MOVABLE_TYPE);
+
+class QQuickProfiler : public QQmlAbstractProfilerAdapter {
+ Q_OBJECT
+public:
+
+ template<EventType DetailType>
+ static void addEvent()
+ {
+ s_instance->processMessage(QQuickProfilerData(s_instance->timestamp(), 1 << Event,
+ 1 << DetailType));
+ }
+
+ static void animationFrame(qint64 delta)
+ {
+ int animCount = QUnifiedTimer::instance()->runningAnimationCount();
+
+ if (animCount > 0 && delta > 0) {
+ s_instance->processMessage(QQuickProfilerData(s_instance->timestamp(), 1 << Event,
+ 1 << AnimationFrame, 1000 / (int)delta /* trim fps to integer */, animCount));
+ }
+ }
+
+ template<SceneGraphFrameType FrameType1, SceneGraphFrameType FrameType2>
+ static void sceneGraphFrame(qint64 value1, qint64 value2 = -1, qint64 value3 = -1,
+ qint64 value4 = -1, qint64 value5 = -1)
+ {
+ s_instance->processMessage(QQuickProfilerData(s_instance->timestamp(), 1 << SceneGraphFrame,
+ 1 << FrameType1 | 1 << FrameType2, value1, value2, value3, value4, value5));
+ }
+
+ template<PixmapEventType PixmapState>
+ static void pixmapStateChanged(const QUrl &url)
+ {
+ s_instance->processMessage(QQuickProfilerData(s_instance->timestamp(),
+ 1 << PixmapCacheEvent, 1 << PixmapState, url));
+ }
+
+ static void pixmapLoadingFinished(const QUrl &url, const QSize &size)
+ {
+ s_instance->processMessage(QQuickProfilerData(s_instance->timestamp(),
+ 1 << PixmapCacheEvent,
+ (1 << PixmapLoadingFinished) | ((size.width() > 0 && size.height() > 0) ? (1 << PixmapSizeKnown) : 0),
+ url, size.width(), size.height()));
+ }
+
+ template<PixmapEventType CountType>
+ static void pixmapCountChanged(const QUrl &url, int count)
+ {
+ s_instance->processMessage(QQuickProfilerData(s_instance->timestamp(),
+ 1 << PixmapCacheEvent, 1 << CountType, url, 0, 0, 0, count));
+ }
+
+ qint64 timestamp() { return m_timer.nsecsElapsed(); }
+
+ qint64 sendMessages(qint64 until, QList<QByteArray> &messages);
+
+ static bool enabled;
+
+ static void initialize();
+
+ virtual ~QQuickProfiler();
+
+protected:
+ int next;
+ static QQuickProfiler *s_instance;
+ QMutex m_dataMutex;
+ QElapsedTimer m_timer;
+ QVarLengthArray<QQuickProfilerData> m_data;
+
+ QQuickProfiler(QQmlProfilerService *service);
+
+ void processMessage(const QQuickProfilerData &message)
+ {
+ QMutexLocker lock(&m_dataMutex);
+ m_data.append(message);
+ }
+
+protected slots:
+ void startProfilingImpl();
+ void stopProfilingImpl();
+ void reportDataImpl();
+ void setTimer(const QElapsedTimer &t);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri
index fae1103d47..ce409bd10d 100644
--- a/src/quick/util/util.pri
+++ b/src/quick/util/util.pri
@@ -25,7 +25,8 @@ SOURCES += \
$$PWD/qquickglobal.cpp \
$$PWD/qquickanimator.cpp \
$$PWD/qquickanimatorjob.cpp \
- $$PWD/qquickanimatorcontroller.cpp
+ $$PWD/qquickanimatorcontroller.cpp \
+ $$PWD/qquickprofiler.cpp
HEADERS += \
$$PWD/qquickapplication_p.h\
@@ -58,4 +59,5 @@ HEADERS += \
$$PWD/qquickanimator_p.h \
$$PWD/qquickanimator_p_p.h \
$$PWD/qquickanimatorjob_p.h \
- $$PWD/qquickanimatorcontroller_p.h
+ $$PWD/qquickanimatorcontroller_p.h \
+ $$PWD/qquickprofiler_p.h