Commit 36e8cf3c authored by Morten Johan Sørvig's avatar Morten Johan Sørvig
Browse files

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: default avatarLorn Potter <lorn.potter@gmail.com>
No related merge requests found
Showing with 44 additions and 1 deletion
......@@ -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
......
......@@ -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
......
......@@ -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
......@@ -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; }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment