Revision control

Copy as Markdown

// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// Qt-Security score:significant reason:default
#ifndef QQUICK3DPROFILER_P_H
#define QQUICK3DPROFILER_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 <QtCore/private/qabstractanimation_p.h>
#include <QtQuick/private/qtquickglobal_p.h>
#include <QtQuick3DUtils/private/qtquick3dutilsglobal_p.h>
#if QT_CONFIG(qml_debug)
#include <QtQml/private/qqmlprofilerdefinitions_p.h>
#endif
#include <QtCore/qurl.h>
#include <QtCore/qsize.h>
#include <QtCore/qmutex.h>
#include <QtCore/qthreadstorage.h>
QT_BEGIN_NAMESPACE
#if !QT_CONFIG(qml_debug)
#define Q_QUICK3D_PROFILE_IF_ENABLED(feature, Code)
struct QQuick3DProfiler {
};
#define Q_QUICK3D_PROFILING_ENABLED false
#define Q_QUICK3D_PROFILE_REGISTER_D(obj)
#define Q_QUICK3D_PROFILE_REGISTER(obj)
#define Q_QUICK3D_PROFILE_ID
#define Q_QUICK3D_PROFILE_GET_ID
#define Q_QUICK3D_PROFILE_ASSIGN_ID_SG(obj, bgnode)
#define Q_QUICK3D_PROFILE_ASSIGN_ID(bgnode, obj)
#else
#define Q_QUICK3D_PROFILE_IF_ENABLED(feature, Code)\
if (QQuick3DProfiler::featuresEnabled & (1 << feature)) {\
Code;\
} else\
(void)0
#define Q_QUICK3D_PROFILING_ENABLED (QQuick3DProfiler::featuresEnabled > 0)
#define Q_QUICK3D_PROFILE_REGISTER_D(obj) d->profilingId = QQuick3DProfiler::registerObject(obj)
#define Q_QUICK3D_PROFILE_REGISTER(obj) profilingId = QQuick3DProfiler::registerObject(obj)
#define Q_QUICK3D_PROFILE_ID int profilingId = -1;
#define Q_QUICK3D_PROFILE_GET_ID(Object) \
QQuick3DObjectPrivate::get(Object)->profilingId
#define Q_QUICK3D_PROFILE_ASSIGN_ID_SG(obj, bgnode) \
if (bgnode) \
(bgnode)->profilingId = Q_QUICK3D_PROFILE_GET_ID(obj);
#define Q_QUICK3D_PROFILE_ASSIGN_ID(bgnode, obj) \
(obj)->profilingId = (bgnode)->profilingId;
struct Q_QUICK3DUTILS_EXPORT QQuick3DProfilerData
{
static constexpr int s_numSupportedIds = 2;
QQuick3DProfilerData() {}
QQuick3DProfilerData(qint64 time, int messageType, int detailType, qint64 d1, qint64 d2)
: time(time), messageType(messageType), detailType(detailType), subdata1(d1), subdata2(d2) {}
QQuick3DProfilerData(qint64 time, int messageType, int detailType, qint64 d1, qint64 d2, const QList<int> &ids);
qint64 time = 0;
qint32 messageType = 0;
qint32 detailType = 0;
qint64 subdata1 = 0;
qint64 subdata2 = 0;
qint32 ids[s_numSupportedIds] = {0}; // keep this even sized
};
Q_DECLARE_TYPEINFO(QQuick3DProfilerData, Q_RELOCATABLE_TYPE);
class Q_QUICK3DUTILS_EXPORT QQuick3DProfilerSceneGraphData : public QQmlProfilerDefinitions {
private:
static const uint s_numSceneGraphTimings = 2;
static const uint s_numNestedTimings = 5;
struct Timings {
uint nesting = 0;
qint64 values[s_numNestedTimings][s_numSceneGraphTimings + 1] = {};
};
struct TimingData
{
Timings timings[MaximumQuick3DFrameType] = {};
};
static QThreadStorage<TimingData> eventTimings;
public:
template<int type, bool inc>
qint64 *timings()
{
Timings *timings;
qint64 *t;
timings = &eventTimings.localData().timings[type];
if (inc) {
Q_ASSERT(timings->nesting < s_numNestedTimings);
t = timings->values[timings->nesting];
timings->nesting++;
} else {
timings->nesting--;
t = timings->values[timings->nesting];
}
return t;
}
};
class Q_QUICK3DUTILS_EXPORT QQuick3DProfiler : public QObject, public QQmlProfilerDefinitions {
Q_OBJECT
public:
enum Quick3DStage {
Quick3DStageBegin,
Quick3DStageEnd
};
template<int FrameType>
static void recordSceneGraphTimestamp(uint position)
{
s_instance->m_sceneGraphData.timings<FrameType, true>()[position] = s_instance->timestamp();
}
template<int FrameType>
static void reportQuick3DFrame(uint position, quint64 payload)
{
qint64 *timings = s_instance->m_sceneGraphData.timings<FrameType, false>();
timings[position] = s_instance->timestamp();
s_instance->processMessage(QQuick3DProfilerData(
timings[position], Quick3DFrame, FrameType,
timings[1] - timings[0],
payload));
}
template<int FrameType>
static void reportQuick3DFrame(uint position, quint64 payload, const QByteArray str)
{
qint64 *timings = s_instance->m_sceneGraphData.timings<FrameType, false>();
timings[position] = s_instance->timestamp();
int sid = registerString(str);
QList<int> poids;
poids << sid;
s_instance->processMessage(QQuick3DProfilerData(
timings[position], Quick3DFrame, FrameType,
timings[1] - timings[0],
payload,
poids));
}
template<int FrameType>
static void reportQuick3DFrame(uint position, quint64 payload, int poid)
{
qint64 *timings = s_instance->m_sceneGraphData.timings<FrameType, false>();
timings[position] = s_instance->timestamp();
QList<int> poids;
poids << poid;
s_instance->processMessage(QQuick3DProfilerData(
timings[position], Quick3DFrame, FrameType,
timings[1] - timings[0],
payload,
poids));
}
template<int FrameType>
static void reportQuick3DFrame(uint position, quint64 payload, int poid, const QByteArray str)
{
qint64 *timings = s_instance->m_sceneGraphData.timings<FrameType, false>();
timings[position] = s_instance->timestamp();
int sid = registerString(str);
QList<int> poids;
poids << poid << sid;
s_instance->processMessage(QQuick3DProfilerData(
timings[position], Quick3DFrame, FrameType,
timings[1] - timings[0],
payload,
poids));
}
template<int FrameType>
static void reportQuick3DFrame(uint position, quint64 payload, const QList<int> &poids)
{
qint64 *timings = s_instance->m_sceneGraphData.timings<FrameType, false>();
timings[position] = s_instance->timestamp();
s_instance->processMessage(QQuick3DProfilerData(
timings[position], Quick3DFrame, FrameType,
timings[1] - timings[0],
payload,
poids));
}
qint64 timestamp() { return m_timer.nsecsElapsed(); }
static quint64 featuresEnabled;
static void initialize(QObject *parent);
~QQuick3DProfiler() override;
static int registerObject(const QObject *object);
static int registerString(const QByteArray &string);
signals:
void dataReady(const QVector<QQuick3DProfilerData> &data, const QHash<int, QByteArray> &eventData);
protected:
friend class QQuick3DProfilerAdapter;
static QMutex s_eventDataMutex;
static QHash<QByteArray, int> s_eventData;
static QHash<int, QByteArray> s_eventDataRev;
static QQuick3DProfiler *s_instance;
QMutex m_dataMutex;
QElapsedTimer m_timer;
QVector<QQuick3DProfilerData> m_data;
QQuick3DProfilerSceneGraphData m_sceneGraphData;
QQuick3DProfiler(QObject *parent);
void processMessage(const QQuick3DProfilerData &message)
{
QMutexLocker lock(&m_dataMutex);
m_data.append(message);
}
void startProfilingImpl(quint64 features);
void stopProfilingImpl();
void reportDataImpl();
void setTimer(const QElapsedTimer &t);
};
#endif // QT_CONFIG(qml_debug)
#define Q_QUICK3D_PROFILE(feature, Method) \
Q_QUICK3D_PROFILE_IF_ENABLED(feature, QQuick3DProfiler::Method)
#define Q_QUICK3D_PROFILE_START(Type) \
Q_QUICK3D_PROFILE_IF_ENABLED(QQuick3DProfiler::ProfileQuick3D, \
(QQuick3DProfiler::recordSceneGraphTimestamp<Type>(QQuick3DProfiler::Quick3DStageBegin)))
#define Q_QUICK3D_PROFILE_END(Type) \
Q_QUICK3D_PROFILE_IF_ENABLED(QQuick3DProfiler::ProfileQuick3D, \
(QQuick3DProfiler::reportQuick3DFrame<Type>(QQuick3DProfiler::Quick3DStageEnd, 0, 0)))
#define Q_QUICK3D_PROFILE_END_WITH_PAYLOAD(Type, Payload) \
Q_QUICK3D_PROFILE_IF_ENABLED(QQuick3DProfiler::ProfileQuick3D, \
(QQuick3DProfiler::reportQuick3DFrame<Type>(QQuick3DProfiler::Quick3DStageEnd, \
Payload)))
#define Q_QUICK3D_PROFILE_END_WITH_STRING(Type, Payload, Str) \
Q_QUICK3D_PROFILE_IF_ENABLED(QQuick3DProfiler::ProfileQuick3D, \
(QQuick3DProfiler::reportQuick3DFrame<Type>(QQuick3DProfiler::Quick3DStageEnd, \
Payload, Str)))
#define Q_QUICK3D_PROFILE_END_WITH_ID(Type, Payload, POID) \
Q_QUICK3D_PROFILE_IF_ENABLED(QQuick3DProfiler::ProfileQuick3D, \
(QQuick3DProfiler::reportQuick3DFrame<Type>(QQuick3DProfiler::Quick3DStageEnd, \
Payload, POID)))
#define Q_QUICK3D_PROFILE_END_WITH_IDS(Type, Payload, POIDs) \
Q_QUICK3D_PROFILE_IF_ENABLED(QQuick3DProfiler::ProfileQuick3D, \
(QQuick3DProfiler::reportQuick3DFrame<Type>(QQuick3DProfiler::Quick3DStageEnd, \
Payload, POIDs)))
#define Q_QUICK3D_PROFILE_END_WITH_ALL(Type, Payload, POID, Str) \
Q_QUICK3D_PROFILE_IF_ENABLED(QQuick3DProfiler::ProfileQuick3D, \
(QQuick3DProfiler::reportQuick3DFrame<Type>(QQuick3DProfiler::Quick3DStageEnd, \
Payload, POID, Str)))
#define QSSG_RENDERPASS_NAME(passName, level, face) \
QByteArrayLiteral(passName)+ QByteArrayLiteral("_level_") + QByteArray::number(level) \
+ QByteArrayLiteral("_face_") + QByteArrayView(QSSGBaseTypeHelpers::toString(QSSGRenderTextureCubeFace(face)))
QT_END_NAMESPACE
#endif