diff options
Diffstat (limited to 'src/quick/scenegraph/qsgthreadedrenderloop.cpp')
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 111 |
1 files changed, 40 insertions, 71 deletions
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 561ebff8dd..6974271dc7 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -1,8 +1,8 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 The Qt Company Ltd. ** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com> -** Contact: http://www.qt-project.org/legal +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. ** @@ -11,9 +11,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -24,8 +24,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -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 @@ -155,7 +145,7 @@ const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4); // called. const QEvent::Type WM_Grab = QEvent::Type(QEvent::User + 5); -template <typename T> T *windowFor(const QList<T> list, QQuickWindow *window) +template <typename T> T *windowFor(const QList<T> &list, QQuickWindow *window) { for (int i=0; i<list.size(); ++i) { const T &t = list.at(i); @@ -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())); @@ -715,10 +706,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 @@ -868,7 +856,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; @@ -958,6 +945,14 @@ void QSGThreadedRenderLoop::handleObscurity(Window *w) } +void QSGThreadedRenderLoop::handleUpdateRequest(QQuickWindow *window) +{ + qCDebug(QSG_LOG_RENDERLOOP) << "- polish and sync update request"; + Window *w = windowFor(m_windows, window); + if (w) + polishAndSync(w); +} + void QSGThreadedRenderLoop::maybeUpdate(QQuickWindow *window) { Window *w = windowFor(m_windows, window); @@ -1085,8 +1080,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; } @@ -1096,8 +1089,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; } @@ -1106,16 +1097,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; @@ -1130,6 +1122,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(); @@ -1137,9 +1130,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"; @@ -1160,22 +1151,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) @@ -1188,15 +1164,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: |