diff options
author | Gunnar Sletta <gunnar.sletta@jollamobile.com> | 2014-07-04 23:50:50 +0200 |
---|---|---|
committer | Gunnar Sletta <gunnar.sletta@jollamobile.com> | 2014-07-29 19:13:39 +0200 |
commit | 15ce5d915b6bda4bf1d3c85cbdc79b2e11690bca (patch) | |
tree | 83668da1212904d81a73208211861c36a74261ee /src | |
parent | 9c67029ee5aca18ae02e740afbf6d0f883799ebd (diff) |
Introducing QQuickWindow::scheduleRenderJob()
[ChangeLog][QtQuick][QQuickWindow] Added
QQuickWindow::scheduleRenderJob(), a convenience alternative to the
equivalent signals for one-shot tasks.
Change-Id: I5e4f0d67d5223f7fd77bca394e2a85810fadd335
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 107 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.h | 12 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 9 |
3 files changed, 127 insertions, 1 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 63e57615ba..0c71254169 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -66,6 +66,7 @@ #include <QtCore/qvarlengtharray.h> #include <QtCore/qabstractanimation.h> #include <QtCore/QLibraryInfo> +#include <QtCore/QRunnable> #include <QtQml/qqmlincubator.h> #include <QtQuick/private/qquickpixmapcache_p.h> @@ -331,6 +332,7 @@ void QQuickWindowPrivate::syncSceneGraph() animationController->beforeNodeSync(); emit q->beforeSynchronizing(); + runAndClearJobs(&beforeSynchronizingJobs); if (!renderer) { forceUpdate(contentItem); @@ -354,6 +356,7 @@ void QQuickWindowPrivate::syncSceneGraph() renderer->setCustomRenderMode(customRenderMode); emit q->afterSynchronizing(); + runAndClearJobs(&afterSynchronizingJobs); context->endSync(); } @@ -367,6 +370,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size) animationController->advance(); emit q->beforeRendering(); + runAndClearJobs(&beforeRenderingJobs); int fboId = 0; const qreal devicePixelRatio = q->devicePixelRatio(); renderer->setDeviceRect(QRect(QPoint(0, 0), size * devicePixelRatio)); @@ -381,6 +385,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size) context->renderNextFrame(renderer, fboId); emit q->afterRendering(); + runAndClearJobs(&afterRenderingJobs); } QQuickWindowPrivate::QQuickWindowPrivate() @@ -470,6 +475,8 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) QObject::connect(q, SIGNAL(focusObjectChanged(QObject*)), q, SIGNAL(activeFocusItemChanged())); QObject::connect(q, SIGNAL(screenChanged(QScreen*)), q, SLOT(forcePolish())); + + QObject::connect(q, SIGNAL(frameSwapped()), q, SLOT(runJobsAfterSwap()), Qt::DirectConnection); } /*! @@ -1101,6 +1108,19 @@ QQuickWindow::~QQuickWindow() delete d->dragGrabber; d->dragGrabber = 0; #endif delete d->contentItem; d->contentItem = 0; + + d->renderJobMutex.lock(); + qDeleteAll(d->beforeSynchronizingJobs); + d->beforeSynchronizingJobs.clear(); + qDeleteAll(d->afterSynchronizingJobs); + d->afterSynchronizingJobs.clear(); + qDeleteAll(d->beforeRenderingJobs); + d->beforeRenderingJobs.clear(); + qDeleteAll(d->afterRenderingJobs); + d->afterRenderingJobs.clear(); + qDeleteAll(d->afterSwapJobs); + d->afterSwapJobs.clear(); + d->renderJobMutex.unlock(); } /*! @@ -2815,8 +2835,13 @@ void QQuickWindow::cleanupSceneGraph() delete d->renderer->rootNode(); delete d->renderer; - d->renderer = 0; + + d->runAndClearJobs(&d->beforeSynchronizingJobs); + d->runAndClearJobs(&d->afterSynchronizingJobs); + d->runAndClearJobs(&d->beforeRenderingJobs); + d->runAndClearJobs(&d->afterRenderingJobs); + d->runAndClearJobs(&d->afterSwapJobs); } void QQuickWindow::setTransientParent_helper(QQuickWindow *window) @@ -3834,6 +3859,86 @@ bool QQuickWindow::glslIsCoreProfile() const flashing or bouncing the taskbar entry. */ +/*! + \enum QQuickWindow::RenderJobSchedule + \since 5.4 + + \value ScheduleBeforeSynchronizing Before synchronization. + \value ScheduleAfterSynchronizing After synchronization. + \value ScheduleBeforeRendering Before rendering. + \value ScheduleAfterRendering After rendering. + \value ScheduleAfterSwap After the frame is swapped. + + \sa {Scene Graph and Rendering} + */ + +/*! + \since 5.4 + + Schedule \a job to run when the rendering of this window reaches + the given \a stage. + + This is a convenience to the equivalent signals in QQuickWindow for + "one shot" tasks. + + The window takes ownership over \a job and will delete it when the + job is completed. + + If rendering is shut down before \a job has a chance to run, the + job will be run and then deleted as part of the scene graph cleanup. + If the window is never shown and no rendering happens before the QQuickWindow + is destroyed, all pending jobs will be destroyed without their run() + method being called. + + If the rendering is happening on a different thread, then the job + will happen on the rendering thread. + + \note This function does not trigger rendering; the job + will be stored run until rendering is triggered elsewhere. + To force the job to run earlier, call QQuickWindow::update(); + + \sa beforeRendering(), afterRendering(), beforeSynchronizing(), + afterSynchronizing(), frameSwapped(), sceneGraphInvalidated() + */ + +void QQuickWindow::scheduleRenderJob(QRunnable *job, RenderStage stage) +{ + Q_D(QQuickWindow); + + d->renderJobMutex.lock(); + if (stage == BeforeSynchronizingStage) + d->beforeSynchronizingJobs << job; + else if (stage == AfterSynchronizingStage) + d->afterSynchronizingJobs << job; + else if (stage == BeforeRenderingStage) + d->beforeRenderingJobs << job; + else if (stage == AfterRenderingStage) + d->afterRenderingJobs << job; + else if (stage == AfterSwapStage) + d->afterSwapJobs << job; + d->renderJobMutex.unlock(); +} + +void QQuickWindowPrivate::runAndClearJobs(QList<QRunnable *> *jobs) +{ + renderJobMutex.lock(); + QList<QRunnable *> jobList = *jobs; + jobs->clear(); + renderJobMutex.unlock(); + + foreach (QRunnable *r, jobList) { + r->run(); + delete r; + } +} + +void QQuickWindow::runJobsAfterSwap() +{ + Q_D(QQuickWindow); + d->runAndClearJobs(&d->afterSwapJobs); +} + + #include "moc_qquickwindow.cpp" QT_END_NAMESPACE diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index 4ed663ee6e..6353f6a30c 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE +class QRunnable; class QQuickItem; class QSGTexture; class QInputMethodEvent; @@ -79,6 +80,14 @@ public: TextureCanUseAtlas = 0x0008 }; + enum RenderStage { + BeforeSynchronizingStage, + AfterSynchronizingStage, + BeforeRenderingStage, + AfterRenderingStage, + AfterSwapStage + }; + Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption) enum SceneGraphError { @@ -145,6 +154,8 @@ public: QString glslVersion() const; bool glslIsCoreProfile() const; + void scheduleRenderJob(QRunnable *job, RenderStage schedule); + Q_SIGNALS: void frameSwapped(); Q_REVISION(2) void openglContextCreated(QOpenGLContext *context); @@ -196,6 +207,7 @@ private Q_SLOTS: void cleanupSceneGraph(); void forcePolish(); void setTransientParent_helper(QQuickWindow *window); + void runJobsAfterSwap(); private: friend class QQuickItem; diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 8faaf6489b..66202aec5c 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -256,6 +256,15 @@ public: static bool defaultFormatInitialized; static QSurfaceFormat defaultFormat; + QMutex renderJobMutex; + QList<QRunnable *> beforeSynchronizingJobs; + QList<QRunnable *> afterSynchronizingJobs; + QList<QRunnable *> beforeRenderingJobs; + QList<QRunnable *> afterRenderingJobs; + QList<QRunnable *> afterSwapJobs; + + void runAndClearJobs(QList<QRunnable *> *jobs); + private: static void cleanupNodesOnShutdown(QQuickItem *); }; |