diff options
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 12 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgnode.cpp | 15 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgnode.h | 1 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgrenderer.cpp | 19 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgadaptationlayer.cpp | 11 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext.cpp | 4 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext_p.h | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultlayer.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultlayer_p.h | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgrenderloop.cpp | 21 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgrenderloop_p.h | 1 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 95 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop_p.h | 5 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgwindowsrenderloop.cpp | 39 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgatlastexture.cpp | 16 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgtexture.cpp | 21 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgvertexcolormaterial.cpp | 9 |
17 files changed, 132 insertions, 143 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 838251ed08..ef125e07a9 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -128,8 +128,9 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material) if (shader) return shader; - if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::profilingSceneGraph()) + 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(); @@ -159,8 +160,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; @@ -173,8 +173,9 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate if (shader) return shader; - if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::profilingSceneGraph()) + 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); @@ -190,8 +191,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/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp index 58b6462d23..6271d12998 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.cpp +++ b/src/quick/scenegraph/coreapi/qsgnode.cpp @@ -575,6 +575,21 @@ void QSGNode::removeAllChildNodes() } } +/*! + * \internal + * + * Reparents all nodes of this node to \a newParent. + */ +void QSGNode::reparentChildNodesTo(QSGNode *newParent) +{ + Q_ASSERT_X(!newParent->parent(), "QSGNode::reparentChildNodesTo", "newParent is already part of a hierarchy"); + + for (QSGNode *c = firstChild(); c; c = c->nextSibling()) { + removeChildNode(c); + newParent->appendChildNode(c); + } +} + int QSGNode::childCount() const { diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h index dfacd84288..059cbeebdf 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.h +++ b/src/quick/scenegraph/coreapi/qsgnode.h @@ -132,6 +132,7 @@ public: void appendChildNode(QSGNode *node); void insertChildNodeBefore(QSGNode *node, QSGNode *before); void insertChildNodeAfter(QSGNode *node, QSGNode *after); + void reparentChildNodesTo(QSGNode *newParent); int childCount() const; QSGNode *childAtIndex(int i) const; diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index dd089425f6..ce86408434 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -176,10 +176,11 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) m_is_rendering = true; - bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled() || - QQuickProfiler::profilingSceneGraph(); + bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled(); if (profileFrames) frameTimer.start(); + Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRendererFrame); + qint64 bindTime = 0; qint64 renderTime = 0; @@ -189,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) { @@ -206,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; @@ -218,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)); - } /*! @@ -273,15 +269,16 @@ void QSGRenderer::preprocess() } } - bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled()|| - QQuickProfiler::profilingSceneGraph(); + 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 80234d54f5..e0b96a45b6 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -153,10 +153,10 @@ void QSGDistanceFieldGlyphCache::update() if (m_pendingGlyphs.isEmpty()) return; - bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled() || - QQuickProfiler::profilingSceneGraph(); + 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) { @@ -169,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(); @@ -183,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/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index b5bdbde3ad..2a0fae9f72 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -378,6 +378,7 @@ void QSGContext::renderContextInitialized(QSGRenderContext *renderContext) QByteArray all; foreach (const QByteArray &e, exts) all += ' ' + e; qCDebug(QSG_LOG_INFO) << "GL_EXTENSIONS: " << all.constData(); qCDebug(QSG_LOG_INFO) << "Max Texture Size: " << renderContext->maxTextureSize(); + qCDebug(QSG_LOG_INFO) << "Debug context: " << format.testOption(QSurfaceFormat::DebugContext); } d->mutex.unlock(); @@ -468,8 +469,11 @@ QSurfaceFormat QSGContext::defaultSurfaceFormat() const QSurfaceFormat format = QSurfaceFormat::defaultFormat(); static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); static bool useStencil = qEnvironmentVariableIsEmpty("QSG_NO_STENCIL_BUFFER"); + static bool enableDebug = qEnvironmentVariableIsSet("QSG_OPENGL_DEBUG"); format.setDepthBufferSize(useDepth ? 24 : 0); format.setStencilBufferSize(useStencil ? 8 : 0); + if (enableDebug) + format.setOption(QSurfaceFormat::DebugContext); if (QQuickWindow::hasDefaultAlphaBuffer()) format.setAlphaBufferSize(8); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 184b8248d5..91788d82d4 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -93,7 +93,7 @@ public: QOpenGLContext *openglContext() const { return m_gl; } QSGContext *sceneGraphContext() const { return m_sg; } - bool isValid() const { return m_gl; } + virtual bool isValid() const { return m_gl; } virtual void initialize(QOpenGLContext *context); virtual void invalidate(); diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp index 450a9fbee0..2d114aebd5 100644 --- a/src/quick/scenegraph/qsgdefaultlayer.cpp +++ b/src/quick/scenegraph/qsgdefaultlayer.cpp @@ -57,7 +57,7 @@ namespace public: BindableFbo(QOpenGLFramebufferObject *fbo, QSGDepthStencilBuffer *depthStencil); virtual ~BindableFbo(); - virtual void bind() const; + void bind() const Q_DECL_OVERRIDE; private: QOpenGLFramebufferObject *m_fbo; QSGDepthStencilBuffer *m_depthStencil; diff --git a/src/quick/scenegraph/qsgdefaultlayer_p.h b/src/quick/scenegraph/qsgdefaultlayer_p.h index 44c74d7cfd..0615045d60 100644 --- a/src/quick/scenegraph/qsgdefaultlayer_p.h +++ b/src/quick/scenegraph/qsgdefaultlayer_p.h @@ -54,7 +54,7 @@ public: QSGDefaultLayer(QSGRenderContext *context); ~QSGDefaultLayer(); - virtual bool updateTexture(); + bool updateTexture() Q_DECL_OVERRIDE; // The item's "paint node", not effect node. QSGNode *item() const { return m_item; } diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index c66915d19d..ecfbe0323c 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -347,17 +347,17 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) } QElapsedTimer renderTimer; qint64 renderTime = 0, syncTime = 0, polishTime = 0; - bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || - QQuickProfiler::profilingSceneGraph(); + 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(); @@ -365,11 +365,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->effectiveDevicePixelRatio(), false, false); @@ -377,13 +379,15 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) } if (alsoSwap && window->isVisible()) { - gl->swapBuffers(window); + if (!cd->customRenderStage || !cd->customRenderStage->swap()) + gl->swapBuffers(window); cd->fireFrameSwapped(); } 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(); @@ -398,11 +402,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/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h index e9b58c60ba..8d3214db60 100644 --- a/src/quick/scenegraph/qsgrenderloop_p.h +++ b/src/quick/scenegraph/qsgrenderloop_p.h @@ -64,6 +64,7 @@ public: virtual void update(QQuickWindow *window) = 0; virtual void maybeUpdate(QQuickWindow *window) = 0; + virtual void handleUpdateRequest(QQuickWindow *) { } virtual QAnimationDriver *animationDriver() const = 0; diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 155b52b31a..5218552427 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -105,16 +105,6 @@ QT_BEGIN_NAMESPACE #define QSG_RT_PAD " (RT)" -static int get_env_int(const char *name, int defaultValue) -{ - QByteArray content = qgetenv(name); - - bool ok = false; - int value = content.toInt(&ok); - return ok ? value : defaultValue; -} - - static inline int qsgrl_animation_interval() { qreal refreshRate = QGuiApplication::primaryScreen()->refreshRate(); // To work around that some platforms wrongfully return 0 or something @@ -531,12 +521,12 @@ void QSGRenderThread::sync(bool inExpose) void QSGRenderThread::syncAndRender() { - bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || - QQuickProfiler::profilingSceneGraph(); + 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(); @@ -544,20 +534,24 @@ void QSGRenderThread::syncAndRender() qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "syncAndRender()"; syncResultedInChanges = false; + QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); - uint pending = pendingUpdate; + bool repaintRequested = (pendingUpdate & RepaintRequest) || d->customRenderStage; + bool syncRequested = pendingUpdate & SyncRequest; + bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest; pendingUpdate = 0; - if (pending & SyncRequest) { + if (syncRequested) { qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- updatePending, doing sync"; - sync(pending == ExposeRequest); + sync(exposeRequested); } #ifndef QSG_NO_RENDER_TIMING if (profileFrames) syncTime = threadTimer.nsecsElapsed(); #endif + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame); - if (!syncResultedInChanges && ((pending & RepaintRequest) == 0)) { + if (!syncResultedInChanges && !repaintRequested) { qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- no changes, render aborted"; int waitTime = vsyncDelta - (int) waitTimer.elapsed(); if (waitTime > 0) @@ -567,7 +561,6 @@ void QSGRenderThread::syncAndRender() qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering started"; - QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); if (animatorDriver->isRunning()) { d->animationController->lock(); @@ -582,9 +575,12 @@ void QSGRenderThread::syncAndRender() d->renderSceneGraph(windowSize); if (profileFrames) renderTime = threadTimer.nsecsElapsed(); - gl->swapBuffers(window); + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame); + if (!d->customRenderStage || !d->customRenderStage->swap()) + 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"; } @@ -595,7 +591,7 @@ void QSGRenderThread::syncAndRender() // that to avoid blocking the GUI thread in the case where it // has started rendering with a bad window, causing makeCurrent to // fail or if the window has a bad size. - if (pending == ExposeRequest) { + if (exposeRequested) { qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- wake Gui after initial expose"; waitCondition.wakeOne(); mutex.unlock(); @@ -609,10 +605,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); } @@ -695,8 +688,6 @@ QSGThreadedRenderLoop::QSGThreadedRenderLoop() m_animation_driver = sg->createAnimationDriver(this); - m_exhaust_delay = get_env_int("QML_EXHAUST_DELAY", 5); - connect(m_animation_driver, SIGNAL(started()), this, SLOT(animationStarted())); connect(m_animation_driver, SIGNAL(stopped()), this, SLOT(animationStopped())); @@ -710,10 +701,7 @@ QSGRenderContext *QSGThreadedRenderLoop::createRenderContext(QSGContext *sg) con void QSGThreadedRenderLoop::maybePostPolishRequest(Window *w) { - if (w->timerId == 0) { - qCDebug(QSG_LOG_RENDERLOOP) << "- posting update"; - w->timerId = startTimer(m_exhaust_delay, Qt::PreciseTimer); - } + w->window->requestUpdate(); } QAnimationDriver *QSGThreadedRenderLoop::animationDriver() const @@ -863,7 +851,6 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window) win.window = window; win.actualWindowFormat = window->format(); win.thread = new QSGRenderThread(this, QQuickWindowPrivate::get(window)->context); - win.timerId = 0; win.updateDuringSync = false; win.forceRenderPass = true; // also covered by polishAndSync(inExpose=true), but doesn't hurt m_windows << win; @@ -953,6 +940,14 @@ void QSGThreadedRenderLoop::handleObscurity(Window *w) } +void QSGThreadedRenderLoop::handleUpdateRequest(QQuickWindow *window) +{ + qCDebug(QSG_LOG_RENDERLOOP) << "- polish and sync update request"; + foreach (const Window &w, m_windows) + if (w.window == window) + polishAndSync(const_cast<Window *>(&w)); +} + void QSGThreadedRenderLoop::maybeUpdate(QQuickWindow *window) { Window *w = windowFor(m_windows, window); @@ -1080,8 +1075,6 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) QQuickWindow *window = w->window; if (!w->thread || !w->thread->window) { qCDebug(QSG_LOG_RENDERLOOP) << "- not exposed, abort"; - killTimer(w->timerId); - w->timerId = 0; return; } @@ -1091,8 +1084,6 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) w = windowFor(m_windows, window); if (!w || !w->thread || !w->thread->window) { qCDebug(QSG_LOG_RENDERLOOP) << "- removed after event flushing, abort"; - killTimer(w->timerId); - w->timerId = 0; return; } @@ -1101,16 +1092,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::profilingSceneGraph(); + 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; @@ -1125,6 +1117,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(); @@ -1132,9 +1125,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) if (profileFrames) syncTime = timer.nsecsElapsed(); - - killTimer(w->timerId); - w->timerId = 0; + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync); if (m_animation_timer == 0 && m_animation_driver->isRunning()) { qCDebug(QSG_LOG_RENDERLOOP) << "- advancing animations"; @@ -1155,22 +1146,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)); -} - -QSGThreadedRenderLoop::Window *QSGThreadedRenderLoop::windowForTimer(int timerId) const -{ - for (int i=0; i<m_windows.size(); ++i) { - if (m_windows.at(i).timerId == timerId) { - return const_cast<Window *>(&m_windows.at(i)); - break; - } - } - return 0; + Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync); } bool QSGThreadedRenderLoop::event(QEvent *e) @@ -1183,15 +1159,8 @@ bool QSGThreadedRenderLoop::event(QEvent *e) qCDebug(QSG_LOG_RENDERLOOP) << "- ticking non-visual timer"; m_animation_driver->advance(); emit timeToIncubate(); - } else { - qCDebug(QSG_LOG_RENDERLOOP) << "- polish and sync timer"; - Window *w = windowForTimer(te->timerId()); - if (w) - polishAndSync(w); - else - killTimer(te->timerId()); + return true; } - return true; } default: diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h index 82f314a6af..b3db56e5f9 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h +++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h @@ -60,6 +60,8 @@ public: void update(QQuickWindow *window); void maybeUpdate(QQuickWindow *window); + void handleUpdateRequest(QQuickWindow *window); + QSGContext *sceneGraphContext() const; QSGRenderContext *createRenderContext(QSGContext *) const; @@ -80,7 +82,6 @@ private: QQuickWindow *window; QSGRenderThread *thread; QSurfaceFormat actualWindowFormat; - int timerId; uint updateDuringSync : 1; uint forceRenderPass : 1; }; @@ -89,7 +90,6 @@ private: void releaseResources(Window *window, bool inDestructor); bool checkAndResetForceUpdate(QQuickWindow *window); - Window *windowForTimer(int timerId) const; bool anyoneShowing() const; void initialize(); @@ -109,7 +109,6 @@ private: QList<Window> m_windows; int m_animation_timer; - int m_exhaust_delay; bool m_lockedForSync; }; diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 070d6b82fd..469cd1d21b 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::profilingSceneGraph()) \ - 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() @@ -346,7 +350,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"); @@ -354,8 +359,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, @@ -390,27 +394,29 @@ 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); + if (!d->customRenderStage || !d->customRenderStage->swap()) + m_gl->swapBuffers(window); + QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_swapped); RLDEBUG(" - frameDone"); d->fireFrameSwapped(); @@ -423,10 +429,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 5edcb5d67a..cb82d721ca 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -377,10 +377,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::profilingSceneGraph(); + 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) { @@ -393,12 +395,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 fc5050014e..673323baa2 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -633,10 +633,12 @@ void QSGPlainTexture::bind() m_dirty_texture = false; - bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled() || - QQuickProfiler::profilingSceneGraph(); + 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) { @@ -645,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(); @@ -662,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... @@ -692,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); @@ -734,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); @@ -762,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/scenegraph/util/qsgvertexcolormaterial.cpp b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp index 3a84bf6219..be24ebe76d 100644 --- a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp +++ b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp @@ -99,9 +99,12 @@ void QSGVertexColorMaterialShader::initialize() The geometry to be rendered with vertex color must have the following layout. Attribute position 0 must contain vertices. Attribute position 1 must contain colors, a tuple of 4 values with RGBA layout. Both floats in the range of 0 to 1 and unsigned bytes in - the range 0 to 255 are valid for the color values. The - QSGGeometry::defaultAttributes_ColoredPoint2D() constructs an attribute set - compatible with this material. + the range 0 to 255 are valid for the color values. + + \note The rendering pipeline expects pixels with premultiplied alpha. + + QSGGeometry::defaultAttributes_ColoredPoint2D() can be used to construct an attribute + set that is compatible with this material. The vertex color material respects both current opacity and current matrix when updating it's rendering state. |