aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/debugger/qqmlprofilerdefinitions_p.h26
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp12
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer.cpp17
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp10
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp17
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp23
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp36
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp15
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp20
-rw-r--r--src/quick/util/qquickprofiler.cpp2
-rw-r--r--src/quick/util/qquickprofiler_p.h119
11 files changed, 204 insertions, 93 deletions
diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h
index 92bab93300..7abff8857e 100644
--- a/src/qml/debugger/qqmlprofilerdefinitions_p.h
+++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h
@@ -107,18 +107,20 @@ struct QQmlProfilerDefinitions {
};
enum SceneGraphFrameType {
- SceneGraphRendererFrame,
- SceneGraphAdaptationLayerFrame,
- SceneGraphContextFrame,
- SceneGraphRenderLoopFrame,
- SceneGraphTexturePrepare,
- SceneGraphTextureDeletion,
- SceneGraphPolishAndSync,
- SceneGraphWindowsRenderShow,
- SceneGraphWindowsAnimations,
- SceneGraphPolishFrame,
-
- MaximumSceneGraphFrameType
+ SceneGraphRendererFrame, // Render Thread
+ SceneGraphAdaptationLayerFrame, // Render Thread
+ SceneGraphContextFrame, // Render Thread
+ SceneGraphRenderLoopFrame, // Render Thread
+ SceneGraphTexturePrepare, // Render Thread
+ SceneGraphTextureDeletion, // Render Thread
+ SceneGraphPolishAndSync, // GUI Thread
+ SceneGraphWindowsRenderShow, // Unused
+ SceneGraphWindowsAnimations, // GUI Thread
+ SceneGraphPolishFrame, // GUI Thread
+
+ MaximumSceneGraphFrameType,
+ NumRenderThreadFrameTypes = SceneGraphPolishAndSync,
+ NumGUIThreadFrameTypes = MaximumSceneGraphFrameType - NumRenderThreadFrameTypes
};
typedef QV4::Profiling::MemoryType MemoryType;
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 83234bd32c..173858b21d 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -124,8 +124,9 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material)
if (shader)
return shader;
- if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::enabled)
+ if (QSG_LOG_TIME_COMPILATION().isDebugEnabled())
qsg_renderer_timer.start();
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
QSGMaterialShader *s = material->createShader();
QOpenGLContext *ctx = QOpenGLContext::currentContext();
@@ -155,8 +156,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material)
qCDebug(QSG_LOG_TIME_COMPILATION, "shader compiled in %dms", (int) qsg_renderer_timer.elapsed());
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphContextFrame, (
- qsg_renderer_timer.nsecsElapsed()));
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphContextFrame);
rewrittenShaders[type] = shader;
return shader;
@@ -169,8 +169,9 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
if (shader)
return shader;
- if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::enabled)
+ if (QSG_LOG_TIME_COMPILATION().isDebugEnabled())
qsg_renderer_timer.start();
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
QSGMaterialShader *s = static_cast<QSGMaterialShader *>(material->createShader());
context->compile(s, material);
@@ -186,8 +187,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
qCDebug(QSG_LOG_TIME_COMPILATION, "shader compiled in %dms (no rewrite)", (int) qsg_renderer_timer.elapsed());
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphContextFrame, (
- qsg_renderer_timer.nsecsElapsed()));
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphContextFrame);
return shader;
}
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
index d62802e854..ce86408434 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
@@ -176,9 +176,11 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
m_is_rendering = true;
- bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled() || QQuickProfiler::enabled;
+ bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled();
if (profileFrames)
frameTimer.start();
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRendererFrame);
+
qint64 bindTime = 0;
qint64 renderTime = 0;
@@ -188,6 +190,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
bindable.bind();
if (profileFrames)
bindTime = frameTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame);
// Sanity check that attribute registers are disabled
if (qsg_sanity_check) {
@@ -205,6 +208,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
render();
if (profileFrames)
renderTime = frameTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRendererFrame);
m_is_rendering = false;
m_changed_emitted = false;
@@ -217,13 +221,6 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
int((updatePassTime - preprocessTime) / 1000000),
int((bindTime - updatePassTime) / 1000000),
int((renderTime - bindTime) / 1000000));
-
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphRendererFrame, (
- preprocessTime,
- updatePassTime - preprocessTime,
- bindTime - updatePassTime,
- renderTime - bindTime));
-
}
/*!
@@ -272,14 +269,16 @@ void QSGRenderer::preprocess()
}
}
- bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled()|| QQuickProfiler::enabled;
+ bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled();
if (profileFrames)
preprocessTime = frameTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame);
nodeUpdater()->updateStates(root);
if (profileFrames)
updatePassTime = frameTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame);
}
void QSGRenderer::addNodesToPreprocess(QSGNode *node)
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index faf2762acc..db32f656e1 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -153,9 +153,10 @@ void QSGDistanceFieldGlyphCache::update()
if (m_pendingGlyphs.isEmpty())
return;
- bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled() || QQuickProfiler::enabled;
+ bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled();
if (profileFrames)
qsg_render_timer.start();
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphAdaptationLayerFrame);
QList<QDistanceField> distanceFields;
for (int i = 0; i < m_pendingGlyphs.size(); ++i) {
@@ -168,6 +169,7 @@ void QSGDistanceFieldGlyphCache::update()
int count = m_pendingGlyphs.size();
if (profileFrames)
renderTime = qsg_render_timer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphAdaptationLayerFrame);
m_pendingGlyphs.reset();
@@ -182,10 +184,8 @@ void QSGDistanceFieldGlyphCache::update()
int(renderTime / 1000000),
int((now - (renderTime / 1000000))));
}
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphAdaptationLayerFrame, (
- count,
- renderTime,
- qsg_render_timer.nsecsElapsed() - renderTime));
+ Q_QUICK_SG_PROFILE_END_WITH_PAYLOAD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
+ (qint64)count);
}
void QSGDistanceFieldGlyphCache::setGlyphsPosition(const QList<GlyphPosition> &glyphs)
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index dc0939c023..0de3c84491 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -362,16 +362,17 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
}
QElapsedTimer renderTimer;
qint64 renderTime = 0, syncTime = 0, polishTime = 0;
- bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled;
+ bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled();
if (profileFrames)
renderTimer.start();
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
cd->polishItems();
- if (profileFrames) {
+ if (profileFrames)
polishTime = renderTimer.nsecsElapsed();
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphPolishFrame, (polishTime));
- }
+ Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
+ QQuickProfiler::SceneGraphRenderLoopFrame);
emit window->afterAnimating();
@@ -379,11 +380,13 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
cd->renderSceneGraph(window->size());
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
if (data.grabOnly) {
grabContent = qt_gl_read_framebuffer(window->size() * window->devicePixelRatio(), false, false);
@@ -398,6 +401,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
qint64 swapTime = 0;
if (profileFrames)
swapTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame);
if (QSG_LOG_TIME_RENDERLOOP().isDebugEnabled()) {
static QTime lastFrameTime = QTime::currentTime();
@@ -412,11 +416,6 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
lastFrameTime = QTime::currentTime();
}
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphRenderLoopFrame, (
- syncTime - polishTime,
- renderTime - syncTime,
- swapTime - renderTime));
-
// Might have been set during syncSceneGraph()
if (data.updatePending)
maybeUpdate(window);
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 4e70c3f0a2..92c478b54f 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -521,11 +521,12 @@ void QSGRenderThread::sync(bool inExpose)
void QSGRenderThread::syncAndRender()
{
- bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled;
+ bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled();
if (profileFrames) {
sinceLastTime = threadTimer.nsecsElapsed();
threadTimer.start();
}
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
QElapsedTimer waitTimer;
waitTimer.start();
@@ -552,6 +553,7 @@ void QSGRenderThread::syncAndRender()
if (profileFrames)
syncTime = threadTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering started";
@@ -570,9 +572,11 @@ void QSGRenderThread::syncAndRender()
d->renderSceneGraph(windowSize);
if (profileFrames)
renderTime = threadTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
gl->swapBuffers(window);
d->fireFrameSwapped();
} else {
+ Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame, 1);
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window not ready, skipping render";
}
@@ -597,10 +601,7 @@ void QSGRenderThread::syncAndRender()
int(threadTimer.elapsed() - renderTime / 1000000));
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphRenderLoopFrame, (
- syncTime,
- renderTime - syncTime,
- threadTimer.nsecsElapsed() - renderTime));
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame);
}
@@ -1087,15 +1088,17 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
qint64 polishTime = 0;
qint64 waitTime = 0;
qint64 syncTime = 0;
- bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled;
+ bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled();
if (profileFrames)
timer.start();
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
d->polishItems();
if (profileFrames)
polishTime = timer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync);
w->updateDuringSync = false;
@@ -1109,6 +1112,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
qCDebug(QSG_LOG_RENDERLOOP) << "- wait for sync";
if (profileFrames)
waitTime = timer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync);
w->thread->waitCondition.wait(&w->thread->mutex);
m_lockedForSync = false;
w->thread->mutex.unlock();
@@ -1116,6 +1120,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
if (profileFrames)
syncTime = timer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync);
killTimer(w->timerId);
w->timerId = 0;
@@ -1139,11 +1144,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
<< ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000
<< " - (on Gui thread) " << window;
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphPolishAndSync, (
- polishTime,
- waitTime - polishTime,
- syncTime - waitTime,
- timer.nsecsElapsed() - syncTime));
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync);
}
QSGThreadedRenderLoop::Window *QSGThreadedRenderLoop::windowForTimer(int timerId) const
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index f2731e347b..b55977296c 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -53,10 +53,14 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_
#define RLDEBUG(x) qCDebug(QSG_LOG_RENDERLOOP) << x;
static QElapsedTimer qsg_render_timer;
-#define QSG_RENDER_TIMING_SAMPLE(sampleName) \
+#define QSG_LOG_TIME_SAMPLE(sampleName) \
qint64 sampleName = 0; \
- if (QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled) \
- sampleName = qsg_render_timer.nsecsElapsed()
+ if (QSG_LOG_TIME_RENDERLOOP().isDebugEnabled()) \
+ sampleName = qsg_render_timer.nsecsElapsed(); \
+
+#define QSG_RENDER_TIMING_SAMPLE(frameType, sampleName) \
+ QSG_LOG_TIME_SAMPLE(sampleName) \
+ Q_QUICK_SG_PROFILE_RECORD(frameType);
QSGWindowsRenderLoop::QSGWindowsRenderLoop()
@@ -360,7 +364,8 @@ void QSGWindowsRenderLoop::render()
if (m_animationDriver->isRunning()) {
RLDEBUG("advancing animations");
- QSG_RENDER_TIMING_SAMPLE(time_start);
+ QSG_LOG_TIME_SAMPLE(time_start);
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphWindowsAnimations);
m_animationDriver->advance();
RLDEBUG("animations advanced");
@@ -368,8 +373,7 @@ void QSGWindowsRenderLoop::render()
"animations ticked in %dms",
int((qsg_render_timer.nsecsElapsed() - time_start)/1000000));
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphWindowsAnimations, (
- qsg_render_timer.nsecsElapsed() - time_start));
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphWindowsAnimations);
// It is not given that animations triggered another maybeUpdate()
// and thus another render pass, so to keep things running,
@@ -404,27 +408,28 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
if (!windowData(window))
return;
- QSG_RENDER_TIMING_SAMPLE(time_start);
+ QSG_LOG_TIME_SAMPLE(time_start);
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
RLDEBUG(" - polishing");
d->polishItems();
- QSG_RENDER_TIMING_SAMPLE(time_polished);
-
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphPolishFrame, (time_polished - time_start));
+ QSG_LOG_TIME_SAMPLE(time_polished);
+ Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
+ QQuickProfiler::SceneGraphRenderLoopFrame);
emit window->afterAnimating();
RLDEBUG(" - syncing");
d->syncSceneGraph();
- QSG_RENDER_TIMING_SAMPLE(time_synced);
+ QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_synced);
RLDEBUG(" - rendering");
d->renderSceneGraph(window->size());
- QSG_RENDER_TIMING_SAMPLE(time_rendered);
+ QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_rendered);
RLDEBUG(" - swapping");
m_gl->swapBuffers(window);
- QSG_RENDER_TIMING_SAMPLE(time_swapped);
+ QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_swapped);
RLDEBUG(" - frameDone");
d->fireFrameSwapped();
@@ -437,10 +442,7 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
<< ", swap=" << (time_swapped - time_rendered) / 1000000
<< " - " << window;
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphRenderLoopFrame, (
- time_synced - time_polished,
- time_rendered - time_synced,
- time_swapped - time_rendered));
+ Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphRenderLoopFrame);
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index c396507ab6..bc091edffe 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -368,9 +368,12 @@ void Atlas::bind(QSGTexture::Filtering filtering)
// Upload all pending images..
for (int i=0; i<m_pending_uploads.size(); ++i) {
- bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled() || QQuickProfiler::enabled;
+ bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled();
if (profileFrames)
qsg_renderer_timer.start();
+ // Skip bind, convert, swizzle; they're irrelevant
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
+ Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, 3);
if (m_externalFormat == GL_BGRA &&
!m_use_bgra_fallback) {
@@ -383,12 +386,10 @@ void Atlas::bind(QSGTexture::Filtering filtering)
<< "ms (" << m_pending_uploads.at(i)->image().width() << "x"
<< m_pending_uploads.at(i)->image().height() << ")";
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphTexturePrepare, (
- 0, // bind (not relevant)
- 0, // convert (not relevant)
- 0, // swizzle (not relevant)
- qsg_renderer_timer.nsecsElapsed(), // (upload all of the above)
- 0)); // mipmap (not used ever...)
+ // Skip mipmap; unused
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare);
+ Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, 1);
+ Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphTexturePrepare);
}
GLenum f = filtering == QSGTexture::Nearest ? GL_NEAREST : GL_LINEAR;
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index 4b3ff8bed5..3bb0cb0074 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -633,9 +633,12 @@ void QSGPlainTexture::bind()
m_dirty_texture = false;
- bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled() || QQuickProfiler::enabled;
+ bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled();
if (profileFrames)
qsg_renderer_timer.start();
+ Q_QUICK_SG_PROFILE_START_SYNCHRONIZED(QQuickProfiler::SceneGraphTexturePrepare,
+ QQuickProfiler::SceneGraphTextureDeletion);
+
if (m_image.isNull()) {
if (m_texture_id && m_owns_texture) {
@@ -644,8 +647,7 @@ void QSGPlainTexture::bind()
(int) qsg_renderer_timer.elapsed(),
m_texture_size.width(),
m_texture_size.height());
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphTextureDeletion, (
- qsg_renderer_timer.nsecsElapsed()));
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTextureDeletion);
}
m_texture_id = 0;
m_texture_size = QSize();
@@ -661,6 +663,7 @@ void QSGPlainTexture::bind()
qint64 bindTime = 0;
if (profileFrames)
bindTime = qsg_renderer_timer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare);
// ### TODO: check for out-of-memory situations...
@@ -691,6 +694,7 @@ void QSGPlainTexture::bind()
qint64 convertTime = 0;
if (profileFrames)
convertTime = qsg_renderer_timer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare);
updateBindOptions(m_dirty_bind_options);
@@ -733,12 +737,14 @@ void QSGPlainTexture::bind()
qint64 swizzleTime = 0;
if (profileFrames)
swizzleTime = qsg_renderer_timer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare);
funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_texture_size.width(), m_texture_size.height(), 0, externalFormat, GL_UNSIGNED_BYTE, tmp.constBits());
qint64 uploadTime = 0;
if (profileFrames)
uploadTime = qsg_renderer_timer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare);
if (mipmapFiltering() != QSGTexture::None) {
funcs->glGenerateMipmap(GL_TEXTURE_2D);
@@ -761,13 +767,7 @@ void QSGPlainTexture::bind()
int((mipmapTime - uploadTime)/1000000),
m_texture_size != m_image.size() ? " (scaled to GL_MAX_TEXTURE_SIZE)" : "");
}
-
- Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphTexturePrepare, (
- bindTime,
- convertTime - bindTime,
- swizzleTime - convertTime,
- uploadTime - swizzleTime,
- qsg_renderer_timer.nsecsElapsed() - uploadTime));
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTexturePrepare);
m_texture_rect = QRectF(0, 0, 1, 1);
diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp
index 604d6e5cb1..7cb64bbeeb 100644
--- a/src/quick/util/qquickprofiler.cpp
+++ b/src/quick/util/qquickprofiler.cpp
@@ -80,7 +80,7 @@ void QQuickProfilerData::toByteArrays(QList<QByteArray> &messages) const
// 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 << subtime_1 << subtime_2 << subtime_3; break;
+ case QQuickProfiler::SceneGraphAdaptationLayerFrame: ds << subtime_3 << subtime_1 << subtime_2; break;
// ContextFrame: compiling material time
case QQuickProfiler::SceneGraphContextFrame: ds << subtime_1; break;
// RenderLoop: syncTime, renderTime, swapTime
diff --git a/src/quick/util/qquickprofiler_p.h b/src/quick/util/qquickprofiler_p.h
index 3aba3430e4..6796fab912 100644
--- a/src/quick/util/qquickprofiler_p.h
+++ b/src/quick/util/qquickprofiler_p.h
@@ -51,6 +51,7 @@
#include <QUrl>
#include <QSize>
#include <QMutex>
+#include <QThreadStorage>
QT_BEGIN_NAMESPACE
@@ -63,8 +64,30 @@ QT_BEGIN_NAMESPACE
#define Q_QUICK_PROFILE(Method)\
Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::Method)
-#define Q_QUICK_SG_PROFILE(Type, Params)\
- Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::sceneGraphFrame<Type> Params))
+#define Q_QUICK_SG_PROFILE_START(Type)\
+ Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::startSceneGraphFrame<Type>()))
+
+#define Q_QUICK_SG_PROFILE_RECORD(Type)\
+ Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::recordSceneGraphTimestamp<Type>()))
+
+#define Q_QUICK_SG_PROFILE_SKIP(Type, Skip)\
+ Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::skipSceneGraphTimestamps<Type, Skip>()))
+
+#define Q_QUICK_SG_PROFILE_START_SYNCHRONIZED(Type1, Type2)\
+ Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::startSceneGraphFrame<Type1, Type2>()))
+
+#define Q_QUICK_SG_PROFILE_SWITCH(Type1, Type2) \
+ Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::reportSceneGraphFrame<Type1, true, Type2>()))
+
+#define Q_QUICK_SG_PROFILE_REPORT(Type)\
+ Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::reportSceneGraphFrame<Type, false>()))
+
+#define Q_QUICK_SG_PROFILE_END(Type)\
+ Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::reportSceneGraphFrame<Type, true>()))
+
+#define Q_QUICK_SG_PROFILE_END_WITH_PAYLOAD(Type, Payload)\
+ Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::reportSceneGraphFrame<Type, true>(Payload)))
+
// This struct is somewhat dangerous to use:
@@ -133,6 +156,39 @@ struct Q_AUTOTEST_EXPORT QQuickProfilerData
Q_DECLARE_TYPEINFO(QQuickProfilerData, Q_MOVABLE_TYPE);
+class QQuickProfilerSceneGraphData : public QQmlProfilerDefinitions {
+private:
+ static const uint s_numSceneGraphTimings = 5;
+
+ template<uint size>
+ struct TimingData {
+ qint64 values[size][s_numSceneGraphTimings + 1];
+ int offsets[size];
+ };
+
+ QThreadStorage<TimingData<NumRenderThreadFrameTypes> > renderThreadTimings;
+ TimingData<NumGUIThreadFrameTypes> guiThreadTimings;
+
+public:
+ template<SceneGraphFrameType type>
+ qint64 *timings()
+ {
+ if (type < NumRenderThreadFrameTypes)
+ return renderThreadTimings.localData().values[type];
+ else
+ return guiThreadTimings.values[type - NumRenderThreadFrameTypes];
+ }
+
+ template<SceneGraphFrameType type>
+ int &offset()
+ {
+ if (type < NumRenderThreadFrameTypes)
+ return renderThreadTimings.localData().offsets[type];
+ else
+ return guiThreadTimings.offsets[type - NumRenderThreadFrameTypes];
+ }
+};
+
class Q_QUICK_PRIVATE_EXPORT QQuickProfiler : public QQmlAbstractProfilerAdapter {
Q_OBJECT
public:
@@ -160,12 +216,62 @@ public:
}
}
+ template<SceneGraphFrameType FrameType1, SceneGraphFrameType FrameType2>
+ static void startSceneGraphFrame()
+ {
+ startSceneGraphFrame<FrameType1>();
+ s_instance->m_sceneGraphData.offset<FrameType2>() = 0;
+ s_instance->m_sceneGraphData.timings<FrameType2>()[0] =
+ s_instance->m_sceneGraphData.timings<FrameType1>()[0];
+ }
+
+ template<SceneGraphFrameType FrameType>
+ static void startSceneGraphFrame()
+ {
+ s_instance->m_sceneGraphData.offset<FrameType>() = 0;
+ s_instance->m_sceneGraphData.timings<FrameType>()[0] = s_instance->timestamp();
+ }
+
template<SceneGraphFrameType FrameType>
- static void sceneGraphFrame(qint64 value1, qint64 value2 = -1, qint64 value3 = -1,
- qint64 value4 = -1, qint64 value5 = -1)
+ static void recordSceneGraphTimestamp()
+ {
+ s_instance->m_sceneGraphData.timings<FrameType>()
+ [++s_instance->m_sceneGraphData.offset<FrameType>()] = s_instance->timestamp();
+ }
+
+ template<SceneGraphFrameType FrameType, uint Skip>
+ static void skipSceneGraphTimestamps()
+ {
+ qint64 *timings = s_instance->m_sceneGraphData.timings<FrameType>();
+ const qint64 last = timings[s_instance->m_sceneGraphData.offset<FrameType>()];
+ for (uint i = 0; i < Skip; ++i)
+ timings[++s_instance->m_sceneGraphData.offset<FrameType>()] = last;
+ }
+
+ template<SceneGraphFrameType FrameType, bool Record>
+ static void reportSceneGraphFrame(quint64 payload = -1)
+ {
+ qint64 *timings = s_instance->m_sceneGraphData.timings<FrameType>();
+ int &offset = s_instance->m_sceneGraphData.offset<FrameType>();
+ if (Record)
+ timings[++offset] = s_instance->timestamp();
+ s_instance->processMessage(QQuickProfilerData(
+ timings[offset], 1 << SceneGraphFrame, 1 << FrameType,
+ offset > 0 ? timings[1] - timings[0] : payload,
+ offset > 1 ? timings[2] - timings[1] : payload,
+ offset > 2 ? timings[3] - timings[2] : payload,
+ offset > 3 ? timings[4] - timings[3] : payload,
+ offset > 4 ? timings[5] - timings[4] : payload));
+ }
+
+ template<SceneGraphFrameType FrameType, bool Record, SceneGraphFrameType SwitchTo>
+ static void reportSceneGraphFrame(quint64 payload = -1)
{
- s_instance->processMessage(QQuickProfilerData(s_instance->timestamp(), 1 << SceneGraphFrame,
- 1 << FrameType, value1, value2, value3, value4, value5));
+ reportSceneGraphFrame<FrameType, Record>(payload);
+ s_instance->m_sceneGraphData.offset<SwitchTo>() = 0;
+ s_instance->m_sceneGraphData.timings<SwitchTo>()[0] =
+ s_instance->m_sceneGraphData.timings<FrameType>()
+ [s_instance->m_sceneGraphData.offset<FrameType>()];
}
template<PixmapEventType PixmapState>
@@ -208,6 +314,7 @@ protected:
QMutex m_dataMutex;
QElapsedTimer m_timer;
QVarLengthArray<QQuickProfilerData> m_data;
+ QQuickProfilerSceneGraphData m_sceneGraphData;
QQuickProfiler(QQmlProfilerService *service);