diff options
author | Morten Johan Sørvig <morten.sorvig@qt.io> | 2018-05-13 00:44:10 +0200 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@qt.io> | 2018-06-01 11:21:20 +0000 |
commit | 36e8cf3cdb50c0447695f35c2e63eed139704c13 (patch) | |
tree | 0eec9bd3ef207062d6af84c9537e74318f950244 /src/plugins | |
parent | 01d75bb804df3129317f5d42d34f1c37efaf52c0 (diff) |
wasm: implement QHtml5Window::requestUpdate()
We’ve already set up emscripten_set_main_loop_arg to
call the main loop callback using requestAnimationFrame.
Pause main loop updates when no updates have been requested.
Restart when requestUpdate() is called again.
Applications can now be completely idle when there
are no updates, or animate continuously if requestUpdate()
is called at the end of the paint event.
Change-Id: I1764b09a698f2d98a0f0e008d93e553f04831d4f
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/html5/qhtml5eventdispatcher.cpp | 25 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5eventdispatcher.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5window.cpp | 17 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5window.h | 1 |
4 files changed, 44 insertions, 1 deletions
diff --git a/src/plugins/platforms/html5/qhtml5eventdispatcher.cpp b/src/plugins/platforms/html5/qhtml5eventdispatcher.cpp index cbf00075b2..1d1e647e5d 100644 --- a/src/plugins/platforms/html5/qhtml5eventdispatcher.cpp +++ b/src/plugins/platforms/html5/qhtml5eventdispatcher.cpp @@ -53,6 +53,16 @@ QHtml5EventDispatcher::~QHtml5EventDispatcher() g_htmlEventDispatcher = nullptr; } +bool QHtml5EventDispatcher::registerRequestUpdateCallback(std::function<void(void)> callback) +{ + if (!g_htmlEventDispatcher || !g_htmlEventDispatcher->m_hasMainLoop) + return false; + + g_htmlEventDispatcher->m_requestUpdateCallbacks.append(callback); + emscripten_resume_main_loop(); + return true; +} + void QHtml5EventDispatcher::maintainTimers() { if (!g_htmlEventDispatcher || !g_htmlEventDispatcher->m_hasMainLoop) @@ -90,7 +100,20 @@ bool QHtml5EventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) // return control to the browser without unwinding the C++ stack. auto callback = [](void *eventDispatcher) { QHtml5EventDispatcher *that = static_cast<QHtml5EventDispatcher *>(eventDispatcher); - that->processEvents(QEventLoop::AllEvents); + + // Save and clear updateRequest callbacks so we can register new ones + auto requestUpdateCallbacksCopy = that->m_requestUpdateCallbacks; + that->m_requestUpdateCallbacks.clear(); + + // Repaint all windows + for (auto callback : qAsConst(requestUpdateCallbacksCopy)) + callback(); + + // Pause main loop if no updates were requested. Updates will be + // restarted again by registerRequestUpdateCallback(). + if (that->m_requestUpdateCallbacks.isEmpty()) + emscripten_pause_main_loop(); + that->doMaintainTimers(); }; int fps = 0; // update using requestAnimationFrame diff --git a/src/plugins/platforms/html5/qhtml5eventdispatcher.h b/src/plugins/platforms/html5/qhtml5eventdispatcher.h index 8b85f5e791..dc2b65857a 100644 --- a/src/plugins/platforms/html5/qhtml5eventdispatcher.h +++ b/src/plugins/platforms/html5/qhtml5eventdispatcher.h @@ -45,6 +45,7 @@ public: explicit QHtml5EventDispatcher(QObject *parent = 0); ~QHtml5EventDispatcher(); + static bool registerRequestUpdateCallback(std::function<void(void)> callback); static void maintainTimers(); protected: @@ -55,6 +56,7 @@ private: bool m_hasMainLoop = false; bool m_hasZeroTimer = false; uint64_t m_currentTargetTime = std::numeric_limits<uint64_t>::max(); + QVector<std::function<void(void)>> m_requestUpdateCallbacks; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/html5/qhtml5window.cpp b/src/plugins/platforms/html5/qhtml5window.cpp index 9fa08f0eca..3a82258a9b 100644 --- a/src/plugins/platforms/html5/qhtml5window.cpp +++ b/src/plugins/platforms/html5/qhtml5window.cpp @@ -30,11 +30,13 @@ #include <qpa/qwindowsysteminterface.h> #include <private/qguiapplication_p.h> #include <QtGui/private/qopenglcontext_p.h> +#include <QtGui/private/qwindow_p.h> #include <QtGui/QOpenGLContext> #include "qhtml5window.h" #include "qhtml5screen.h" #include "qhtml5compositor.h" +#include "qhtml5eventdispatcher.h" #include <QDebug> @@ -393,4 +395,19 @@ qreal QHtml5Window::devicePixelRatio() const return screen()->devicePixelRatio(); } +void QHtml5Window::requestUpdate() +{ + QPointer<QWindow> windowPointer(window()); + bool registered = QHtml5EventDispatcher::registerRequestUpdateCallback([=](){ + if (windowPointer.isNull()) + return; + + QWindowPrivate *wp = static_cast<QWindowPrivate *>(QObjectPrivate::get(windowPointer)); + wp->deliverUpdateRequest(); + }); + + if (!registered) + QPlatformWindow::requestUpdate(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/html5/qhtml5window.h b/src/plugins/platforms/html5/qhtml5window.h index 2681737523..1c44efd526 100644 --- a/src/plugins/platforms/html5/qhtml5window.h +++ b/src/plugins/platforms/html5/qhtml5window.h @@ -72,6 +72,7 @@ public: void lower() override; QRect normalGeometry() const override; qreal devicePixelRatio() const override; + void requestUpdate() override; QHtml5Screen *platformScreen() const; void setBackingStore(QHtml5BackingStore *store) { mBackingStore = store; } |