diff options
author | Ulf Hermann <[email protected]> | 2014-08-29 12:33:48 +0200 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2014-09-12 09:54:11 +0200 |
commit | 7d03dfe4192f164e837df2c5652b83ffe04840d6 (patch) | |
tree | 7fc5806755be62bf783fb9c05fb706412940488c /src/quick | |
parent | 22fcb0efbe0644f5bd29e9538ebb76fa0dbc37b3 (diff) |
Use QQuickProfiler's own timer to sample events
Like that the timings are more accurate.
Task-number: QTBUG-39876
Change-Id: Ia6bdce9c8089417e88797ec3a98c8a3e367f73f2
Reviewed-by: Gunnar Sletta <[email protected]>
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 12 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgrenderer.cpp | 17 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgadaptationlayer.cpp | 10 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgrenderloop.cpp | 17 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 23 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgwindowsrenderloop.cpp | 36 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgatlastexture.cpp | 15 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgtexture.cpp | 20 | ||||
-rw-r--r-- | src/quick/util/qquickprofiler.cpp | 2 | ||||
-rw-r--r-- | src/quick/util/qquickprofiler_p.h | 119 |
10 files changed, 190 insertions, 81 deletions
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); |